COMPUTEPs
FIRST BOOK
ATARI
From The Editors of COMPUTE! Magazine
COMPUTEi's
FIRST BOOK
OF
ATARI
Published by COMPUTE! Books,
A Division of Small System Services, Inc,
Greensboro, North Carolina
AIARI IS a registered trader nark o( Alun. Inc
Copyright © 1981, Small System Services, Inc. All rights reserved. Portions of this material
have appeared in various issues of COMPUTE! Magazine during 1980.
Reproduction or translation of any part of this work beyond that permitted by Sections 107
and 108 of the United States Copyright Act without the permission of the copyright owner
is unlawful.
Printed in the United States of America
ISBN 0-942.386-00-0
10 9 8 7 6 5 4 3 2 1
11
Table of Contents
Introduction Robert Lock, Page iv
Chapter One: Getting To Know Your Atari Page 1
Atari's Marketing Vice President Profiles The Personal
Computer Market Michael S. Tomczyk, Page 2
Atari BASIC And PET Microsoft BASIC. A BASIC
Comparison Joretta Klcpfer, Page 7
The Ouch In Atari BASIC Glenn Fisher and Ron Jeffries, Page 17
Atari BASIC Part II John Victor, Page 19
Chapter Two: Beyond The Basics Page 25
Inside Atari BASIC Larry Isaacs, Page 26
Atari BASIC Structure W. A. Bell, Page 36
Input/Output On The Atari Larry Isaacs, Page 54
Why Machine Language? Jim Butterfield, Page 64
POKin' Around Charles Brannon, Page 67
Printing To The Screen From Machine Language on
The Atari Larry Isaacs, Page 69
Chapter Three: Graphics Page 75
Made In The Shade: An Introduction To "Three-Dimensional"
Graphics On The Atari Computers David D. Thornburg, Page 76
The Fluid Brush Al Baker, Page 80
Color Wheel For The Atari Neil Harris, Page 85
Card Games In Graphics Modes I and 2 William D. Seivert, Page 87
Ticker Tape Atari Messages Eric Martell and Chris Murdock, Page 91
Player/Missile Graphics With The Atari Personal Computer
System Chris Crawford, Page 93
The Basics Of Using POKE in Atari
Graphics Charles G. Former, Page 102
Designing Your Own Atari Graphics Modes Craig Patchett, Page 105
GraphicsOf Polar Functions Henrique Veludo, Page 111
Chapter Four: Programmins Hints Page 115
Reading The Atari Keyboard On The Fly James L. Bruun, Page 116
Atari Sounds Tutorial Jerry White, Page 1 18
Al Baker's Programming Hints: Apple And Atari Al Baker, Page 121
Error Reporting System For The Atari Len Lindsay, Page 129
Chapter Five: Applications Page 135
Atari Tape Data Files: A Consumer Oriented
Approach Al Baker, Page 136
An Atari BASIC Tutorial: Monthly Bar Graph
Program Jerry White, Page 144
Chapter Six: Peripheral Information Page 147
Adding A Voice Track To Atari Programs John Victor, Page 148
The Atari Disk Operating System Roger Beseke, Page 155
Review Of The Atari 810 Disk
System Ron Jeffries and Glenn Fisher, Page
An Atari Tutorial: Atari Disk Menu Len Lindsay, Page
WhatTo Do If You Don't Have Joysticks Steven Schulman, Page
UsingThe Atari Console Switches
Atari Meets The Real World
Appendix A
Atari Memory Locations . . .
Index
James L. Brunn, Page
Richard Kushner, Page
Page
. Ronald Marcuse, Page
Page
59
62
69
72
74
79
80
83
111
INTRODUCTION
Robert Lock, Editor/Publisher, COMPUTE! Magazine
In the fall of 1979, COMPUTE! Magazine began with the initial
vision of providing a resource and applications magazine to owners
and users of various personal computers. We made the decision, at
that time, to support the new personal computers from Atari, Inc.
Our first "Atari Gazette," a monthly part of COMPUTE!, was a
total of three pages long . . . Frequently we struggled, during those
early issues, to seek out good editorial support. Now, every issue of
COMPUTE! routinely carries 40-50 pages of material for the Atari.
And we're still maintaining the same standards of quality. The Atari
reader base is growing faster than ever, and we've never doubted our
decision tci support it.
At the time of this writing, mid-November, 1981, Atari, Inc. is
shipping more personal computers each month, than they did in all
of 1980!
On the pages which follow, you'll find some of the best of the
ATARI Personal Computer® material to appear in COMPUTE!
Magazine during the year 1980.
We've organized the material and designed the book so that it will
be easy to use. If you have any comments or suggestions regarding
this book, or future books you'd like to see from us, please let
us know.
Our special thanks to Charles Brannon and Richard Mansfield of
the Editorial staff at COMPUTE!; Kate Taylor, Dai Rees, and
De Potter of the Production staff; Georgia Papadopoulos, Art
Director; and Harry Blair, our illustrator.
COMPUTE! Books is ii Ji\ision of Snull Svsicni SiTV'kes, Im .,
publishers of COMPUTE! Mii«a:inr.
HJitorinl olliiL- ;iri' loi ;Ul'lI :ii
h25 Fulioii Siavi.C.i-LTiivK.io, NC 27^0i L'SA. I'M^)) 27^-'>SO'i.
CHAPTER ONE
Getting
To Know Your
Atari
Getting To Know Your Atari
Atari's Marketing
Vice President Profiles
the Personal Computer
Market
Michael S. Tomczyk
Atari's corporate character and projected company goals. The inside word.
Conrad jutson
Atari doesn't especially like ?ti}' nic/<na7Tie for their 400/800 personal
computer — "the pop-top computer" — but it's a fact the computer has a
"pop top" where the plug-in RAM /ROM cartridges fit, part of their
innovative user-proof system which also includes interchangeable cards for
the computer's various peripherals. Atari also has a growing array of
educational and game software, including the most sophisticated real-time
simulation game (STAR RAIDERS) in the galaxy . . . a long way from
"Pong," the game that started it all.
Atari's competitors in the personal computer market chuckle at what
they see as the company's attempt to develop the "home" computer
market, in the face of extensive market research that says the home market
won't "happen" for another 4-5 years. Does that mean Atari is wasting
its resources? Are they really going after the home market? Or are they
laying the groundwork for a broader marketing program?
To anstver some of these questions, I interviewed Atari's neiu Vice
President-Sales & Marketing for Personal Computers — he's Conrad
Jutson, who came to Atari in November 1979 with a scant background in
computers but over 20 years experience in consumer electronics at G. E.
(12 yrs.), Toshiba (6 yrs.) and Texas Instruments (3 yrs.).
Jutson began by describing what he sees as the outlook for the
personal computer market: "Small business in the short run will
account for fifty percent of the personal computer business, dollar
wise," he predicted, defining small businesses as those with less than
$1 million in annual gross revenues, employing 10-15 people, and
usually involved in manufacturing or a service-oriented industry.
Typically, they do their bookkeeping by hand through a full or part
time employee, or have it done by a local service. The key to
2
Getting To Know Your Atari
reaching this market, Jutson explained, is being able to show them
that a microcomputer will increase their productivity and make the
investment worthwhile.
The second broad market segment is the consumer market
which, he said, consists of hundreds of subsets.
"If we were to profile the personal computer buyer in the early
80's, it would be a male or female head of household, most likely in
a managerial, administrative or professional position, typically
earning over $25,000 per year and falling into the 25 to 50 age
bracket. Most likely, this person is already familiar with what a
computer can do and can, in the home environment, identify a
need for computing to address various problems and functions.
"There are several millions of these households in the U. S.
that fit into the demographics I've described," he continued. "I
don't believe personal computers will ever be an 'impulse item' off
the shelf, partly because of the expense. So the logical question
becomes, 'Why should I buy a personal computer and what will it
do for me?' "
Jutson's answer to that question — what will a computer do for
me — provided an interesting way cif categorizing the personal
computer market in terms of function. His list of personal computer
uses included . . .
1) Planning and Record Keeping:
"I believe this type of managerial/administrative consumer does not
pay enough attention to his own finances — this is confirmed by the
rapid growth of financial-planning services. With the rapid inflation
of the past few years, projected to continue through the 1980's,
many consumers have found themselves in higher tax brackets with
a higher cost of living that has made their lives more and more
complex and difficult to manage. They've had to cope with budget
planning, financial investments, mortgages, loan payments, credit
unions, payroll stock plans, taxes, and pensions. In this new,
complex environment, consumers have to organize their home
record systems like they do at work — on a daily, year-round basis
instead of just once a year at tax time. They have to look at their
gross income, their investment tradeoffs, and I believe this type of
consumer can justify the purchase of a personal computer with the
appropriate software to meet these various needs . . . given that the
typical first purchase of a personal computer is around
$2000-$2200."
2) Home Education:
The next category of purchase that adds value to the computer is
Getting To Know Your Atari
home education. Jutson noted that a majority of schools and
colleges are requiring some hands-on computer experience and more
and more schools are bring computers into the classroom as
instructional aids. There is already an enormous investment in
home education being made by the American family — cutting
across all demographic strata — in home courseware from
encyclopedias to books. As a supplement to classroom education,
this home courseware can be made much more exciting and "fun"
through visual display and interaction with a computer, Jutson
explained.
3) Personal Development & Interest:
There is also, he said, a huge market in how-to-books, all the way
from how to fix your appliances to learning foreign languages.
Literally hundreds of topics are addressed. Personal computers
provide for active hands-on demonstration for all age brackets and
interests, and speed the learning process.
4) Interactive Entertainment:
Having purchased a personal computer, we're all challenged by
interactive entertainment, he said, whether the entertainment is
one of skill or of strategy. The sale of strategic board games (chess,
backgammon) never seems to let up and, in the skill area, the video
arcades are doing extremely well. So entertainment accounts for a
good deal of software sales.
5) Home Information/Communications:
If we move away from computation and hook up an interface and
telephone modem, we have the capability to hook up to a
timesharing service. Using the computer as a terminal provides a
capability for dialing up and subscribing to a variety of evolving
services. Some, like Micronet and The Source already have a fairly
long menu. Atari has defined an informatin and communications
strategy — obviously it will leverage our installed base of hardware
to help our users gain access and may involve a wholly owned
subsidiary like Warner Amex Cable. Some of the future uses of this
home information system which we can envision include news,
stock data and other services which will cut down driving time,
mailing time, and minimize the hassle of shopping and bill paying.
It's a question now of "getting the players together," he said, and
making it happen.
6) Home Monitor & Control:
The decade of the 1980's will witness a growth of consumer
electronic products deriving in large part from introduction of smart
Getting To Know Your Atari
electronics into the home. The personal computer is the "leading
edge" of these products. By the mid-1980's, he expects to see
dedicated smart electronics — CPU devices which interact with the
electronic environment — in the home. It's unlikely that we'll see
one massive all-purpose CPU controlling everything in the home. It
will happen step by step, beginning with stand alone appliances
containing their own microprocessors and other smart electronics.
These, then, are some of the major uses which Jutson foresees for
personal computers.
He goes on to say that the Atari product was designed to be
easy to use by consumers, easy to access, easily loaded (cartridges),
and easily connected (modular cords).
"Does the end user care about the architecture of the
machine?" he asked rhetorically. "The answer is no. 'What will it do
for me?' That's his major concern. We in the consumer electronics
business are concerned with leveraging technology and bringing
that technology to the consumer for his or her benefit, so why try to
scare the consumer off by making it so he or she has to have a
double E or be a computer programmer to utilize the full capabilities
of a personal computer?"
He drew a parallel between the personal computer industry
and the hcime stereo industry, pointing out that 15 years ago there
were 1500 hi-fi salons in the United States and now there are about
15,000 outlets in the U. S. He feels that computer stores will become
to the computer market what hi-fi specialty shops were originally to
the hi-fi industry, and predicted that a number of stores will
proliferate and become strong chains. A parallel development, he
said, is the entry of general merchandisers such as J. C. Penney
Department Stores into the personal computer distribution scheme.
He emphasized that Atari only started shipping late in the
fourth quarter of 1979 and is just getting into the market with its
400/800 cc:)mputers. Heavy advertising is planned for the second
and third quarters of 1980, including a full dealer support program.
"Having just come out of the gate we have to and will continue
to have, a lot of things to do to strengthen our position in the
industry," he said. "Atari is a young company that has already, in a
few years, achieved significant growth in consumer electronics
products. We have a vertically integrated manufacturing capability,
a marketing staff that understands marketing, distribution, sales,
and sales promotion; and a large blend of research and development
and engineering expertise.
"We believe that the Atari computers are different because
5
Getting To Know Your Atari
from word one they were developed to take away whatever
apprehensions a first time user might have and help him or her feel
good about interfacing with our product. With Atari computers,
you don't have to stop and think before you use them. Of course,
more and more of the younger generation are learning to program
and work with more sophisticated applications, and they will have
the capability of doing so with our product."
Getting To Know Your Atari
Atari BASIC and PET
Microsoft BASIC.
A BASIC Comparison*
Joretta Klepfer
An important item to consider when shopping for a computer is the
language that you will use to communicate. You need to decide
what features are important iov your application and examine the
language accordingly. The brand new Atari computers offer yet
another version of BASIC to tempt programmers and soon-to-be
programmers. The following table is a comparison of the Atari
BASIC (not Microsoft) language and the PET (Microsoft) BASIC
language. I have indicated various features of each and then
commented about the PET and Atari treatment or lack of treatment
of that feature.
The table is not an exhaustive treatment of either language,
but should assist you in learning the "basics" about both languages.
The references used to determine the contents of the table are listed
at the end of this article. You will also want to consult the manuals
provided with the various computer peripherals to learn more about
communication with these devices.
Two sources of information for the Atari BASIC language are
provided with the computers; Atari BASIC by Albrecht, Finkel, and
Brown and BASIC REFERENCE MANUAL (400-800) by Shaw and
Brewster. I would like to share some thoughts with you about each
one. Let's start with Atari BAS7C.
The message on the binding indicates that Atari BASIC is "A
Self-Teaching Guide" and the design of the book is well suited to
accomplish that goal. The format uses proven teaching techniques.
Each chapter begins with the instructional goals for that section and
indicates what your skill levels should be when you finish it. The
material is organized into numbered sections called frames, each of
which presents information and then quizzes you about it. An
important part of the learning process is the active participation on
your part in answering the questions (without peeking at the
answers) and writing the programs that are requested. By all means,
turn your Atari on and use it in conjunction with the book.
Another nice feature is the self-test at the end of each chapter and
Getting To Know Your Atari
at the end of the book. Answers are given to all the questions, but
you will learn more if you take the tests without referring to them.
This book is designed to teach BASIC to a novice and, if used
properly, will accomplish this task very well.
Atari BASIC is not a reference book however, and BASIC
programmers will grow frustrated trying to use it to learn about the
Atari brand of BASIC. A welcome addition to the book sould be a
categorized appendix which lists the Atari BASIC commands,
statements, arithmetic and logical operators, special symbols, and
variable naming conventions. (The built-in functions are already
listed in the appendix, along with the ASCII character codes and
error messages.) This type of "quick reference" section would also
assist those who use this book to learn BASIC as they may need to
refresh their memory from time to time.
The authors indicate in their message 'To The Readers" that
the BASIC in your new Atari computer may be more advanced
than the 8K Atari BASIC they used in writing this book. This
comment is an important one and means that you should read
carefully all the manuals you receive with your unit to determine
what refinements, if any, have been made. I am aware of at least
one: Atari BASIC indicates that a variable name may be a single
letter or a letter and a number, whereas the BASIC REFERENCE
MANUAL gives you the freedom to create variable names of any
length up to 120 characters as king as they begin with a letter. This
difference should not create a lack of confidence in Atari BASIC, for
the variable naming conventions given by Albrecht and company
are probably best for beginners and are obviously still valid.
Atari BASIC docs not include advanced programming
techniques and applications such as creating and manipulating data
files. You wll also not find information on saving and loading
programs on cassette or disk; refer to the special operator's manuals
for I/O information on these peripherals.
If you would like to learn Atari BASIC, Atari BASIC is an
excellent place to start and I highly recommend it. If you already
know BASIC and want to learn the idiosyncrasies of the Atari
brand, read on!
I have been reading a preliminary draft of the new BASIC
REFERENCE MANUAL which will be shipped with the Atari
computers upon its completion. This book is designed in a more
traditional manner, presenting information interspersed with
examples. Be sure to start by reading the preface and the flowchart
of the program for using the manual. Chapter 1 gives a general
Gettins To Know Your Atari
introduction to the manual and its terminology and notation
conventions. A lengthy list of abbreviations is given which you'll
refer to frequently as you read through the manual.
The book is written in a friendly, non-threatening manner
using a style that explains the BASIC language features in a very
"readable," straight-forward way. One very nice feature of the style
of text presentation is that the general format of a statement is
presented first and then an example is given. For the most part,
liberal use of visual aids such as flowcharts, diagrams, tables, and
examples will assist you in your search for facts.
I believe that one or two sections will cause some difficulty for
the beginning programmer, however. One of these is the section on
Input/Output Operations. Dealing with the general format of the
OPEN statement is not a trivial exercise and, since the book is
aimed at all levels of readers, a different treatment of this complex
subject would be easier for the newer computerist to grasp. The
section on game controller functions has no examples longer than
one line and very little information about the use of these functions.
We are told that the "imaginative programmer will think of many
uses" for these functions. Help! Atari — I'm not very imaginative
and others might not be also; in the final manual please give us
some ideas on how to use these unique functions.
I was pleased to find so many useful items in the appendices.
There are several user programs and sample routines listed. A
directory of BASIC keywords gives not only the keyword and a
brief summary, but also gives the chapter number if you need
further reference. A necessary listing is included of error messages
and their corresponding numbers. Utility listings of Decimal to
Hexadecimal conversion tables, and the ATASCII character set as
well as PEEK and POKE information assist the serious programmer.
A listing of trigonometric functions derived from the built-in
functions should interest the scientific programmer. The section on
the keyboard and editing features is a good introduction to this
input device. It was an excellent idea to include, as an appendice,
the glossary and chapter index of the words in the glossary, however
I feel this addition should in no way replace a regular index.
Hopefully, one will be included in the final edition.
Let me restate that all the comments I have made about the
BASIC REFERENCE MANUAL came from examining a rough draft
of the document. I look forward to reading the final copy. I have
confidence that this manual will provide new Atari owners with
ready access to their brand of BASIC.
Getting To Know Your Atari
Variable names
The first two alphanumeric characters form the unique
variable name. However, for ease of reading, the name
could be as long as you wish. Integer variables are created
by adding % to the name. String variables are created by
adding $ to the name.
Variable names may be any length, given memory limitations,
and must start with a letter. 128 different variables are
allowed in a single program. Each letter (rather than just the
first two) is significant.
Subscripted variables
Three subscripts (i.e. three dimensional variables) are allowed.
Original ROM PETs are limited to 255 elements in an array;
on the newer models 8/16/32K PETs there is no limit on the
number of elements except for memory limitations.
Two subscripts (i.e. two-dimensional variables) are allowed.
Subscripts are numbered from 0.
String variables
Character strings may contain up to 255 characters even
though the input buffer is limited to 80 characters. The
concatenation operator + may be used to create longer strings
(within the 255 limit). Non-subscripted string variables need
not be dimensioned. Subscripted string variables must be
dimensioned if the numer of elements in the array is over 10.
The " symbol is used to designate characters strings.
All strings must be dimensioned. There is no limit on the
length of strings; however, a limit of 99 i5 imposed for input of
strings. String arays are not allowed. The + cannot be used
for concatenation.
Integer variables
Integer variables may contain values of -32767 to 32767.
hlot available
Dimensioning variables
No DIMension statement is necessary for arrays, single or
multiple, which have subscripts with values of 10 or less. The
dimension definition may be a constant, a variable, or an
expression.
All character string and numeric arrays must be dimensioned.
Significant digits
Numeric values may contain nine significant digits and are
10
Getting To Know Your Atari
rounded if necessary.
Numeric values may contain nine significant digits and are
truncated if necessary.
Scientific notation
Scientific notation is accepted for input as well as used to
output numbers greater than 9 digits.
Same as PET
Arithmetic operators
+ addition ~ subtraction * multiplication
/ division • exponentiation
Same as PET except * for exponentiation.
Physical line
40 characters
38 characters
Logical line
80 characters
1 1 4 characters
Multiple Statements/line
Multiple statements are allowed and are separated by a :
symbol.
Same as PET
Program Documenting
REM statements allow commenting in the body of your
program.
Same as PET
Assignment
Keyword for an assignment statement is LET, but is not
required. Assignment operator is the = symbol.
Same as PET
Looping
Looping may be accomplished by using the FOR-NEXT-STEP
statements. The STEP value may be an integer or fraction,
positive or negative (therefore allowing the value of the index
to ascend or descend). Whatever the beginning and ending
values of the index are, the loop will be executed at least once.
A single NEXT statement may be used to match multiple FOR
statements. For example: NEXT X,Y,Z.
Same as PET except the same NEXT may not be used for
11
Getting To Know Your Atari
multiple FOR statements. Also, hlEXT must be followed by
its variable. PET allows ^^EXT with an implied variable.
Input
The INPUT statement may have a prompt message included
which will be presented to the user before the ?. This statement
may be used with all types of variables.
You may not include a prompt message in the INPUT
statement. INPUT may not be used with a subscripted
variable.
The READ statement may be used for input with
corresponding DATA statements. Data may be reused if the
RESTORE statement is included appropriately. This type of
input may be used with all type of variables.
READ . . . DATA also may not be used with a subscripted
variable.
The GET statement may be used to input a single byte.
GET statement: same as PET, except that it waits for a
keystroke.
Branching
Unconditional branching may be accomplished by using the
GOTO statement with the statement number of the target
statement. Conditional branching options include ON . . .
GOTO and ON . . . GOSUB statements.
The argument of a GOTO or GOSUB may be a variable or
an expression.
Subroutines
Subroutines are accessed by the GOSUB statement and need a
RETURN statement to indicate the end of the routine.
The command POP can be used to cancel a GOSUB.
Decision-making
The IF - THEN statement uses the conditional operators , ,
= , =, =, and the Boolean operators AND, OR, NOT, for
comparing both numeric and string variable values. Multiple
statements following THEN will be executed if the condition is
true.
AND, OR, and NOT do not operate on the binary level.
Output
The PRINT statement may include variables, arithmetic
expressions, character strings, and constants. There are four
default print positions which are used if items in the list are
12
Getting To Know Your Atari
separated by commas. A semi-colon between items causes
closer printing with character strings being concatenated and
numbers separated by one space. Cursor movement may be
included in strings in the PRINT list. Output is automatically
sent to the screen; a special OPEN statement is needed to
cause printing on the printer. The ? symbol may be used to
represent PRINT when keying in a program. The interpreter
will insert the full word for you.
Same as PET except: the semicolon causes concatenation of
numbers too. LPRINT is used to send output to the printer.
The ? is not spelled out in a program.
Program termination
STOP and END will cause the program to cease execution.
There does not have to be and END statement as the last
statement in the program. The CONT command will allow
you to resume execution after and END or STOP has been
encountered.
COl^T continues on the next line, not necessarily the next
statement.
User-defined functions
DEF FN will allow you to create your own function in BASIC.
User-defined functions are not available in BASIC.
Built-in functions
Standard trigonometric and arithmetic functions are available
as well as special purpose functions to do the following: PEEK
at memory locations, TAB the cursor to a specified column,
SPaCe the cursor the specified number of spaces, indicate the
position of the cursor, give the number of FREe bytes left in
memory, pass a parameter to a USeR machine language
program, and communicate with the PET clock. Functions
may be nested.
Standard trigonometric and arithmetic functions, PRE, and
PEEK are the same as PET. In addition there are CLOG for
base 10 logs, ADR to return decimal memory address of
specified string, DEC, RAD to specify either degrees or
radians for this function. Tab operations are accomplished by
keystroke combination, POSITION, or POKE.
Standard string functions are available, as well as special
functions to designate substrings. The + symbol is used as the
concatenation operator.
13
Getting To Know Your Atari
Same as PET but no functions for substringing. Substrings are
formed by using subscripts with the string variable name to
indicate characters in the string. The + is not used for
concatenation.
Graphics capabilities
Graphics symbols are accessed by pressing the shift key and
the appropriate key (printed on the front of the keys on the
PETs with graphic-style keyboards). These symbols may be
used in PRINT statements to create displays on the screen.
Graphic displays may also be created by using the POKE
statement to insert graphic symbols into the screen memory.
The Atari also has special characters, and provides special
keywords to make creating graphic displays much easier, such
as PLOT, DRAWTO, POSITIO}^, FILL (XIO 18), POKE,
and GRAPHICS. There are nine different graphic modes:
three for text only, gii'ing normal, double wide, and double
size characters; three modes with split screen & four colors;
two with split screen and only two colors; and one high
resolution mode.
Color capabiUties
No color capability
Special keywords are provided to create color displays, such as
COLOR which selects one of four color registers, and
SETCOLOR to specify the hue and luminance of each color
register. B}! usiiig a combination of 16 hues and 18 luminance
settings 128 colors can be created.
Sound capabiUties
Sound is achieved by using the POKE statement to cause
signals to be sent to the parallel user port to which is attached
an external device to produce sound. Rhythm is controlled by
using timing loops. Non-Commodore products are available
for the PET to produce four-voice music similar to the Atari.
Atari provides a SOUND statement which allows
specification of voice, pitch, distortion, and volume. Four
voices can be played at the same time. Control of distrotion
creates interesting sound effects. Rhythm is controlled by
timing loops. The sound is heard through a speaker in the TV
monitor.
Game I/O
No special statements or functions are available to aid in game
14
Getting To Know Your Atari
interaction.
Four functions are provided for ease in programming paddle
and joystick control. They are PADDLE and STICK to
control movement , and PTRIG and STRJG to control the
trigger button.
Files
Files must be OPENed before use with parameters specifying
logical file number, device number, secondary address (permits
intelligent peripherals to operate in any number of modes),
and file name (for tapes, name may be up to 128 characters.
Only 16 characters are used by the system, though). The
CLOSE statement is used to close a file and needs only the
logical file number as a parameter. PRINT#, INPUT#, GET#
are used with tape or disk file I/O. Tape files are recorded
twice to aid in checking for errors.
Files must be OPENed before use with parameters specifying
logical file number, type of operation (read, write, both), file
name (8 characters or less) and device type. PR]'NT#,
INPL;T#, PLJT#, G£T#, andXlO may be used for I/O
operations. NOTE and POINT are functions provided to
facilitate creation of random access files.
Commands
In addition to the standard commands of NEW, LIST, RUN,
CONT, LOAD, SAVE, and POKE, the PET has a VERIFY
command to allow tape files to be verified before erasing
memory, and a CMD command to keep the IEEE'488 Bus
actively listening. The LOAD and SAVE commands may
include a file name.
Atari commands are the same as PET except that Atari has no
VERIFY or CMD commands and file names may not be used
with the CLOAD and OS AVE commands. Program files can
be located on the tape by means of the counter on the cassette.
Error correction & editing
You may erase characters or an entire line while typing. Later
editing of programs is possible by cursor control and line
deletion, by typing the line number and RETURN.
Duplication of lines is possible by first LISTing the line,
changing the line number, and pressing RETURN.
Same as PET, with the addition of three editing functions:
insert line, delete line, and backspace (not the same as delete).
15
Getting To Know Your Atari
Error messages
For syntax errors, the line number is given, but not the cause
of the error. For execution errors, the error message and line
number are printed on the screen.
Syntax errors are indicated by pringing the line and showing
the error in reverse video. Execution errors will cause a
message to appear on the screen giving you an error message to
look up in your manual.
REFERENCES:
1. Boh Albrccht, Lcroy Finlcel, Jerald R. Brown, Atari BASIC. John Wiley & Sons,
Inc., New York (1 97'-:')
2. Carol Shaw, Keith Brewster. BASIC REFERENCE MANUAL, draft, Atari,
Inc., Sunnyvale, CA (1979)
3. CBM User Manual, First Edition. Commodore Business Machines, Santa
Clara, CA (1979)
4. Atari 400 Operators Manual. Atari, Inc., Sunnyvale, CA (1979)
5. Atari 800 Operators Manual. Atari, Inc., Sunnyvale, CA (1979)
16
Getting To Know Your Atari
The Ouch in Atari BASIC
Glenn Fisher and Ron Jeffries
Atari does have some flaws — not catastrophes, but flaws nonetheless.
'Note that the LET operator does permit any name to be used as a
variable name.
After using the Atari 800 for a couple of months, we have found its
version of BASIC to be less than perfect. Please don't misunderstand;
we think that the Atari is a great machine, and is very usable in
spite of these faults. (Other computers will have an equally long list
of defects, they will just be different defects.)
Essentially, there are no character strings in Atari BASIC.
Instead, you have arrays of characters, which ain't the same thing!
(On the good side, however, you are not limited to 255 character
strings as in Microsoft BASIC.)
Would you believe there are no error messages? Well, unless
you consider ERROR 9 to be an error message ... (it means
"Subscript out of range").
There is not a DELETE command. True, few of the competing
BASICS have this essential feature, either. But hope springs eternal.
Atari doesn't have user-defined functions (such as DEE
FNA(X))). This is one of those things you don't miss until you need
it, but when you need it you really need it!
Would you believe — there is not a TAB function? This is
essential when you need to produce neatly formatted output.
AND and OR do not allow you to get at individual bits of a
number. (We see you yawning! but this is more important than you
might suspect, especially when dealing with PEEKs and POKEs.)
Unlike some of Atari's competitors, the Atari does not, repeat
NOT, have any "typeahead." Typeahead allows you to give
commands before previous commands finish, which is very nice
when you want to quickly give a series of commands.
As best we can tell, there is no way to verify a saved file to see
that it got saved properly. Of all the things to omit . . .
The GET statement has an interesting "feature": it waits until
there is a character available. It would be far more convenient if it
returned a special "no data yet" value.
There is a clock in the Atari, but you. Dear Reader, don't get
easy access to it. There are BASICs that give you clock values in
two flavors: as "ticks" since the machine was turned on, and as time
of day measured from when the machine was turned on.
17
Getting To Know Your Atari
Although you can have long, meaningful variable names (all of
whose characters are significant, as opposed to lesser BASICs that
only use the first two characters), there is a problem! Variable
names cannot contain keywords. For example, POINTS and
SCORE are both illegal. (This from a company known for its
games!)
You can't list an open-ended line range. So, you have to say
LIST 500,32767 when what you want to do is list everything from
line 500 on. Sigh!
The INPUT statement doesn't allow a prompt string. You have
to first PRINT the prompt, then do the INPUT. Sure, you can live
with it, but it's a pain.
Here's one for the books: in Atari BASIC you can't READ or
INPUT a value into an array element! (You guessed it: you first
READ into an ordinary variable, then assign that variable to the
array element. I hope that somebody on the design team at least has
a guilty conscience.)
You can only have four colors on the screen at once. (The
Apple has a minimum of six.)
The BREAK key should turn off sound. (It is nice that typing
END will do it, however.)
Obviously, this list represents what we know as of November,
1979, when this was written. To the best of our knowledge, all of the
problems are real. We won't be surprised if some of these flaws are
corrected by Atari. (We may also have misunderstood the
preliminary manuals.)
Finally, if you feel that we are really "down" on the Atari,
please realize that none of the problems mentioned here are serious
enough to keep us from publishing our Atari software product.
Despite its flaws, the Atari is a very useful and flexible personal
computer.
18
Getting To Know Your Atari
Atari BASIC Part II
John Victor
There is no question that the Atari graphics and other machine
features make it superior to its predecessors as a personal computer.
But these great features would be worth little if programmers could
not readily take advantage of them. Atari BASIC makes the use of
color graphics and the generation of sound incredibly easy.
A good example of what can be done with Atari BASIC can
be found in the December issue of INTERFACE AGE. Al Baker of
the Image Producers wrote a short version of the game of SIMON
for the Atari 400 (using about 80 instructions). The game used color
graphics and musical chords. The player attempts to duplicate a
series of notes and colors made by the computer in ever increasing
lengths, and his or her entries are made by pushing a joystick. All of
the versions of this game that I have seen on other computers have
involved some machine language kluges to make them work, but
this Atari program is done entirely in BASIC. The only thing here
that might give the novice programmer some difficulties is the
mathematical relationships of musical notes in a chord. Otherwise,
the program is a model of simplicity.
Although Atari BASIC is not Microsoft BASIC, it is pretty
much like the BASICs found on Apple, PET, and the TRS-80. The
BASIC interpreter resides in a lOK ROM cartridge that plugs into a
slot in the front of the Atari 400 or 800. (Both computers use the
same BASIC.) Its floating point software computes to 9 place
accuracy, it supports multiple statement lines, and it contains the
usual compliment of library routines. Its execution speed appears to
be a bit slower than Applesoft's, but it seems to be better than
TRS'80 Level II. If the BASIC has any deficiencies, it is in the area
of string handling logic. It does not support string arrays.
In some ways the BASIC resembles Apple's integer BASIC.
This is particularly noticeable to Apple programmers when the
computers enters the graphics modes and finds an area at the
bottom of the screen with 4 lines of text. Atari BASIC also allows
the programmer to use variables in GOTO and GOSUB statements
(GOTO A). In addition, the variables can be words, (GOSUB
ERRORROUTINE, GOTO CHOICE, etc.), where CHOICE, for
example, has a line number as a value.
There is one incredible innovation here that makes Atari
BASIC unique. ANY WORD CAN BE USED AS A VARIABLE
19
Getting To Know Your Atari
- EVEN SO-CALLED 'FORBIDDEN' WORDS! The programmer
could use the word END or LIST as a variable. This is definitely not
allowed in any other version of BASIC. LIST can also be used as a
program statement to make the listing of the resident program print
out during the running of the program.
Here are some examples of the use of words as variables in
Atari BASIC. Note that if a program command is goin to be used as
a variable, the word LET must precede it when setting its value.
10 LET LISTING = 1000 :
LET ERRORCOUNT = 2000 ;
LET CHOICE = 3000
120 IF ANSWERS = CORRECT$
THEN RETURN
130 GOTO CHOICE
Variable graphics modes can be entered by giving the graphics
instruction along with a number. Most of these will have an area at
the bottom of the screen for four lines of text. The programmer can
eliminate this area by adding 16 to the number of the graphics
mode. For example, GRAPHICS 3 has four lines of text, but
GRAPHICS 3+16 does not. The graphics instruction will clear the
screen. This can also be deactivated by adding 32 to the graphics
mode number (i.e. GRAPHICS 35 enters GRAPHICS 3 without
clearing the screen.)
The following is a brief description of some of the GRAPHICS
modes.
Graphics O
This is the regular text mode for BASIC. The user gets 24 lines of 40
characters, where the characters can be upper or lower case, regular
or reversed. In addition, the user can access, by pressing the
CONTROL key, a set of pseudo graphics from the keyboard. These
special characters can be used to draw pictures (very much like the
special characters found on the PET).
The user has the ability to change the background color using
the SETCOLOR instruction. The user can change the color
designated by color register 2 (which controls background color)
with the following instruction: SETCOLOR 2,4,14. The screen will
turn light pink, since color register 2 contains the number 4 for red
and the number 14 for the luminescence (0 for darkest to 14 for
20
Getting To Know Your Atari
lightest).
In GRAPHICS the user cannot mix the color of the type,
which can only be a darker or lighter version of the background
color. By setting color register 1 with a luminescence of 0, we get a
dark type against a light background. SETCOLOR 1,0,14 plus
SETCOLOR 2,0,0 will produce a dark grey background with light
characters. Using the luminescences, the user has a choice of about
120 different shades of colors.
Graphics 1 And Graphics 2
There are the "large type" modes, with GRAPHICS 2 prciducing the
largest type. In this mode the characters can be put on the screen in
a variety of ways — they can be PLOTed on like graphics, or
PRINTed on. Different color characters can be made by defining the
characters as upper case, lower case, or reversed characters. When
the type appears on the screen, it appears as all capitals, but the
color of the characters is different. A word printed as lower case
may appear on the screen as upper case red characters, while a word
printed as reverse capitals may be blue. For example, PRINT #6;
"BLUE green" produces 2 "all-capital" words in two different colors.
Graphics 3 To Graphics 1 1
These are the real graphics modes where the computer PLOTs
points at a given screen location. GRAPHICS 3 has the largest
points, and the size goes down as the mode number increases.
GRAPHICS 1 1 is a high rescilution mode. The color of the points is
taken from the color register indicated by the user. COLOR 3 tells
the computer to make the point the same color as specified in cokir
register 3.
To make plotting easier, the graphics modes use a DRAWTO
instruction which will automatically plot a line from any given
point to any other point on the screen, even if the line is a diagonal.
There is also a technic]ue to fill in a predetermined area of the
screen to make a sc]uare of a specific color.
Sound
The user has a choice of four sound generators which can be used to
produce sounds or musical tones. The sound generators can also be
used simultaneously to make chords. Once turned on, each sound
generator stays on until the program reaches and END statement or
the program shuts it off. SOUND 0, 121, 10, 8 plays middle C on
sound register 0.
21
Getting To Know Your Atari
Control Characters
Screen and cursor control functions can be put in a BASIC
program in PRINT statements as control characters. If the user
wants to clear the screen he or she can press the Clear Screen key.
This can also be done in the program by making a PRINT statement
and then pressing the ESCAPE key. When the user hits the Clear
Screen key, a special control character is printed. When the
program is run and the PRINT statement is executed, the screen will
be cleared. The statement will appear like this: PRINT "'^".
Editing And Error Messages
The screen editor on the Atari is the best I've seen. On the Apple,
for example, the user cannot move type around the editor field, but
on the Atari this can be done with simple keyboard inputs. The
user does not need to worry about hidden errors, or relisting since
all changes are immediately visible. If the user is making a line too
long, a bell rings a warning (just as it does on a typewriter).
If a syntax error is made while entering or editing a line, the
BASIC interpreter gives an immediate error message at the carriage
return. This saves quite a bit of debugging time when entering a
program. Unfortunately, for errors encountered during a program
run, the user gets a numbered error message that must be checked
in the manual. There are several of these messages, so they are not
going to be easily memorized.
Computer I/O
In order to get FCC approval for the computer (so it could be
plugged into a regular TV set) Atari had to get approval for all of its
peripheral devices at the same time. So the computer and its
peripherals were designed as one package. This is reflected in the
ease of access to peripherals from the BASIC. There are specific
instructions to access disk, joysticks, printers and the cassette
machine directly from BASIC. In addition to these, the user can
define peripherals using an OPEN instruction. For example: OPEN
#2, 8, 0, "C:" opens the cassette machine for special operations. The
cassette player is now specified by #2. PUT #2, A outputs the value
of A to the cassette player. The user can use INPUT, PRINT, GET,
PUT, etc. as I/O instructions to peripherals.
BASIC can also treat the video screen and the keyboard as
I/O devices for certain kinds of operations.
Atari BASIC, like any other version of BASIC, suffers from
some deficiencies when considering it for some special application.
22
Getting To Know Your Atari
However, in the area of graphics and manijiulation of text displays,
this version of BASIC is, in my opinion, hands down superior to
Apple, PET or TRS-80 BASIC. Its functions are complex, but the
user will find the BASIC relatively easy to use compared to some
other forms of BASIC.
23
24
CHAPTER TWO:
Beyond The Basics
Beyond The Basics
Inside Atari BASIC
Larry Isaacs
For those who want to experiment with the machine, write utility aids, or
just tinker around . . .
This article will present informatin on how ATARI BASIC stores
programs in memory. If you are new to the field of microcomputer
programming, this information should help increase your awareness
of what your ATARI is doing.
The following information is based solely on what I have been
able to observe while working with an ATARI 800. I believe the
information to be accurate. However, it is harci to know how
complete the information is.
Also, for those new to microcomputer programming, the next
section gives some preliminary information which should help make
the rest of the article more understandable.
Preliminary Information
One very important term in the field of microcomputing is the term
"byte." For purposes of this article, it can be considered a number
which can have a value ranging from to 255. The memory in your
ATARI consists of groups of bytes, each byte of which can be
referenced by a unic]ue address. The part of memory which is
changeable, called RAM, starts with a byte at address and
continues with bytes at increasing sequential addresses until the top
of RAM is reached. The top of RAM is determined by the type and
number of memory modules you have in your ATARI.
Bytes, or combinations of bytes, can be used to represent
anything you want. Some common uses for bytes include
representing memory addresses, characters, numbers, and
instructions for the CPU in your ATARI. You will be exposed to
several different uses for bytes in this article. Some of these uses will
make reference to tii'o byte binary numbers. This is where two bytes
are used to represent a number whose value ranges from to 65535.
The decimal value of a two byte binary number can be computed
using the formula: FIRST BYTE + (SECOND BYTE *256).
Also in this article, reference will be made to page zero. Page
zero simply is the first 256 bytes of memory, i.e. addresses through
255. This part of memory differs from the rest of memory in that
these bytes can be referenced using a single byte address. The rest of
memory requires two byte addresses.
26
Beyond The Basics
The Conversion
After typing in a BASIC line, hitting RETURN causes the line to
be passed to the programs found in the ATARI BASIC cartridge.
Here the line will undergo a certain amount of conversion before it
is stored in memory. One part of this conversion involves
converting all of the BASIC reserved words and symbols to a one
byte number called a token.
Another part of the conversion involves replacing each
variable name in the line with an assigned number which will range
from 128 to 255. If a variable name has been previously used, it will
be replaced by the number previously assigned. If it hasn't been
used before, it will be assigned the lowest unused number, starting
with 128 for the first variable name. Also, numbers in the BASIC
line must be converted into the form which the ATARI BASIC uses
before they can be stored in memory.
After the conversion is finished, the line is stored in memory.
If the BASIC line does not have a line number, it will be stored
after the last statement of your BASIC program, and executed
immediately. If it does contain a line number, the converted line
will be inserted in the proper place in your program. After the line
has been executed or stored, your ATARI will wait for you to type
in another line. Even though the line undergoes this conversion,
the order in which the reserved words, variables, and symbols occur
in the line isn't changed when it is stored in memory.
The Memory Format For A Basic Line
Let's begin with the general format of how a BASIC line is stored.
Once a BASIC line has been converted and stored, the line number
is found in the first two bytes of the memory containing the BASIC
line. These bytes form a two byte binary number which has the
value of the line number. The value c)f this number can range from
to 32767.
The third byte contains the total number of bytes in this
BASIC line. This means you can find the first byte of the next line
using the following formula: ADDRESS OF FIRST BYTE OF
NEXT LINE = ADDRESS OF FIRST BYTE OF CURRENT
LINE + NUMBER IN THIRD BYTE OF CURRENT LINE.
The fourth byte contains the number of bytes in the first
statement in the line, including the first four bytes. If the BASIC
line contained only one statement, the third and fourth bytes will
contain the same value. If the line had more thari one statement,
these bytes will be different.
27
Beyond The Basics
Next come the bytes which represent the first statement in the
line. If there is more than one statement, the next byte following the
first statement contains the number of bytes in the first two
statements. Naturally, if there is another statement after the second
one, the first byte after the end of the second statement contains the
number of bytes in the first three statements, etc.
This completes the format of a BASIC line as it is found in
memory. Before going on, let's put this information to use in a short
program which lists out its own line numbers along with the
beginning address of each line. To do this we must first find out
where the first byte of the first line is found. It turns out there is a
two byte binary number found in page zero which contains the
beginning address of the first line. This number is contained in
bytes 136 and 137. Also, we will know when we've reached the end
of the program when we find a line number of 32768, which is one
more than the maximum allowed by ATARI BASIC. The program
to print the line numbers and their beginning addresses is shown in
Listing 1.
Tokens
In order to conserve memory, all of the BASIC reserved words,
operators, and various punctuation symbols are converted into a
one byte number called a token. This conversion also makes
execution simpler and faster. The tokens can be divided into two
groups. One group contains the tokens which occur only at the
beginning of a BASIC statement and the other group contains the
tokens which occur elsewhere in a BASIC statement.
Let's first take a look at the tokens which occur at the
beginning of a BASIC statement. It turns out that all statements
will begin with one of these tokens. After some investigation, I
found that these tokens will range in value from to 54.
The procedure for listing the tokens is fairly simple, though the
actual implementation is a bit more involved than the brief
explanation which follows. The idea is to put "1 REM" as the first
statement of the program. Ther use POKEs to change the line
number and token of this RE^ i statement. By setting the line
number and token to the same number, listing the line will print
the token and corresponding BASIC reserved word. Fortunately the
programs in the BASIC cartridge which do the listing tolerate the
incomplete BASIC statements. The program for displaying these
tokens is shown in Listing 2. Notice when you run this program, no
reserved word is printed for token 54. This is the invisible LET.
28
Beyond The Basics
token which is used for assignment statements which don't begin
with LET.
A similar procedure can be used to list the other tokens as
well. The main differences are to make the first statement "1 REM
A", POKE 54 (the invisible LET token) into the first byte of the
statement, and make the changes for the token to the second byte
of the statement. The values for the tokens which occur after the
beginning of a statement range from 20 to 84. The program for
printing these tokens is given in Listing 3.
After running this program, you will notice there is no
reserved word or symbol printed for token 22. Token 22 is the
terminator token found at the end of each BASIC line, except those
whose last statement is a REM or DATA statement. Also, tokens 56
and 57 didn't print a reserved word or symbol. Both of these tokens
represent the "(" symbol. The "(" doesn't print because these two
tokens are associated with array names, and the "(" symbol is kept
with the associated variable name, as will be seen in the next
section.
Of course you noticed that most of the symbols occur more
than once. There is a different token for each of the different uses of
the symbol. For example, the word " = " has four different tokens.
Token 45 calls for an arithmetic assignment operation as in
A = A+ L Token 46 calls for a string assignment as in A$ = "ABC".
Token 34 is used in arithmetic testing as in IF A= 1 THEN STOP.
And finally, token 52 is the same as token 34 except that it's for
testing strings.
One more token, found after the ones listed in the previous program:
token 14, ivhich indicates a constant is stored in a following six-byte
grouping.
Variable Names And Constants
As each new variable is encountered, it is assigned a number. These
numbers begin with 128 and are assigned sequentially up to 255.
Notice these numbers will fit into one byte. Also, as each new
variable is encountered, the variable name is added to a variable
name list, and 8 bytes of memory are reserved for that variable. In
the case of undimensioned variables, these 8 bytes will contain the
value of the variable. For strings and arrays, these 8 bytes will
contain parameters, with the actual values and characters stored
elsewhere.
This method of handling variables has some advantages. One
advantage is that it keeps usage to a minimum. The variable name is
29
Beyond The Basics
only stored once, and each time that name is referenced in a BASIC
statement, it occupies only one byte in the stored program. Another
advantage is that the address where the value for a variable is stored
can be computed from the assigned number. This isn't true of the
BASIC found in some other microcomputers where values must be
searched for.
There are also some disadvantages as well. First, it limits you
to 128 different variable names. However, the great majority of
programs won't need more than 128 variable names. One other
disadvantage is that, should a variable name be no longer needed,
or accidentally entered due to a typo, there is no quick way to
remove that variable from the variable name list and reuse the 8
bytes reserved for it.
Apparently, the only way to get rid of unwanted variables is to
LIST the program to cassette or disk. For example, LIST "C" will
list the program to cassette. Once the program is saved, use the
NEW command to clear the old program. Then use the ENTER
command to reload the program. For cassette this would be ENTER
"C." Using the LIST command saves the program in character
form. ENTERing the program then causes each line to be converted
again as was done when you first typed it in. Now only the variables
found in the program will be placed in the variable name list, and
space reserved for their value. Using CSAVE and CLOAD won't
do this because these save and load a copy of the memory where the
program is stored. Unwanted variables are saved and loaded with
the rest of the program.
Constants are stored in the BASIC statements along with the
rest of the line. The constant will be preceded by a "14" token as
mentioned previously. Explaining how ATARI BASIC represents
the numbers used as constants and as variable values will require
some explanation about BCD (Binary Coded Decimal) numbers. I
will save this information for a later article.
To give an example of using the information in this section,
let's take a look at the variable name list. Fortunately bytes 130 and
131 contain the address of the beginning of the variable name list.
The list will consist of a string of characters, each character
occupying one byte of memory. To indicate the last character of a
name, ATARI BASIC adds 128 to the value representing that
character. Since the values representing the characters won't exceed
127, the new value will still fit into one byte. To indicate the end of
the list, a is placed in the byte following the last character of the
last name. The program which prints the variable name list is given
30
Beyond The Basics
in Listing 4. Notice, when you run this program, that the "(" is
saved as part of an array name, and the "$" as part of a string name.
Memory Organization
Finally, let's look at how the memory is organized for a BASIC
program. The order in which the various parts of a program are
found in memory is shown in Figure 1. The only part whose
beginning is fixed is the variable name list which begins at address
2048. The beginning of the other parts will move appropriately, as
the program grows. There are addresses in page zero which can be
used to find each of the parts shown in Figure 1. These addresses,
usually called pointers, are shown in Table I. This table includes the
two pointers which were used in the previous programs.
Figure 1. MEMORY ORGANIZATION
Increasing
Addresses
???? End of Array Storage Area
???? Beginning of Array Storage Area
???? End of Program
???? Beginning of Program
???? End of Variable Storage Area
???? Beginning of Variable Storage Area
UU End of Variable Name List
2048 Beginning of Variable Name List
TABLE 1
NAME CONTENTS POINT TO
BON Beginning Of variable Names list
EON End Of variable Name list
BOV Beginning Of Variable storage area
BOP Beginning Of Program
CEL Beginning Of Currently
Executing Line
BOA Beginning Of Array storage area
EOA End of Array storage area
ADDRESSES
130 & 131
132 & 133
134 & 135
136 & 137
138 & 139
140 & 141
142 & 143
Application
For those who are interested in putting this information to use, I will
present one example here. I will try to give more examples in future
issues of COMPUTE!.
31
Beyond The Basics
At some time you may find it useful to be able to
"undimension" some arrays of strings and reuse the memory for
some other arrays and strings. It turns out that the CLR function
only clears the variables found between the BOV (Beginning Of
Variables) pointer and the BOP (Beginning Of Program) pointer.
By temporarily changing the BOP pointer, we can keep some of the
variables from being cleared. The array storage area is cleared by
setting the EOA (End Of Arrays) pointer equal to the BOA
(Beginning Of Arrays) pointer. We can save some of the array
storage area by temporarily changing the BOA pointer.
The listing for this UNDIMENSION routine is shown in
Listing 5. The listing also includes a small demo program to
illustrate its use. Note that all of the names of variables which are to
be cleared should occur in the program prior to any of the names of
variables which are to be saved. This puts the storage for the
variables to be cleared at the beginning of the variable storage area.
Also note that a dummy string which can be cleared is needed by
the UNDIMENSION routine. In your main program, this dummy
string should be dimensioned just before dimensioning the strings
and arrays that you will later clear, as was done in statements 120
and 150. This allows the use of the ADR functions to find the end
of the array area to be saved.
The reason the UNDIMENSION routine is not executed by a
GOSUB is that the return line number is lost in the clearing
process. Loop parameters will also be lost, so the routine shouldn't
be executed while in a FOR.. NEXT loop.
Conclusion
I hope that you found the information in this article
understandable and will find it useful at some point in the future.
The information does show that ATARI BASIC is fairly efficient at
using memory to store programs. Also, there is' very little penalty in
memory usage when using long variable names. If you have any
questions please send them to COMPUTE!.
10 REM PR03<rM to PRINT LIh€ HWBE9S
20 REM AND T^CIR ADDRESSES
30 REM
40 REM Get address of first line
50 «»RESS=F'EEK( 136:;'+FtEK'-: \27 yt25G
60 REM i!kt the 1 irie riUYiber
32
Beyond The Basics
70 LWJM=PEEKX ADDRESS ;'+PEEK( ADDRESS+1 >*25
6
^ RtM Test ior- erid o-f proeram
90 IF LNUM=32768 THEN BO
100 REM Print 1 irie rnjirtber and address
110 ? "LI^€ tMNUri;
120 ? " STARTS AT AODF^SS "iffiDRESS
130 REM Q&t address c-t next line
140 AKiRESS=ADDRESS+F'EB«ADDRESS+2)
150 IJ3T0 70
1 REM
100 REM F-ROGRAM TO F-RIHT THE TOKENS
110 REM imCH BEGIN BA:5IC STATEMENTS
120 FfM i3et. the t«e9iririin5 oi i=rosram
130 E!ftSE=PEEK'; 13G )+PEEK( 137 ):^25fc
140 F£M iZiTariee statema'it terminatijt--
150 F-OKE BASE+5..22
160 ? CHR-*(125;:-^REM CLEAR :SCREEN
170 FBI PRINT TiJKENS
180 FOR: 1=0 TO 54
190 REM i>iarise 1 ine riumber arnd token
200 P0K;E base., r poke Brt5E+4.. I
210 LIST I=REri Print token
220 REM Urdij line teed if needed
2;® IF i>i THe-^ ■' om<.2B>i
240 F-£M Chanse left nursin for columns
250 IF 1=19 T^€N POKE :32.. 12 ^ POSITION 12..
1
260 IF 1=39 THEN POKE 82. 24 ^POSITION 24.
1
270 hCXT I
280 REM Put PTiDsram back to riormal
290 POKE BASE. 1^ F-OKE BA;5E+4..y
300 F-OKE BASE+5.155
310 POKE 82.2-F-OSITION 2.22
1 REM A
100 BftSE=PEEK( 136 )+PEEK< 137 ;'*256
33
Beyond The Basics
110 REM CKanse besiririins token
120 Fir.E mSE+4.54-Fm'E Bft:;E+t./22
130 F.£M Print oper-itor- and function toke
rs
140 PRIHT CHR*(125>
150 FOR 1=20 TO 34
160 F'Ok;E msE...i-?m£ base+s.i
170 LIST I
180 REM !>ido line feeds
190 ? CHR$(2S); ^F 1=22 THEH ? CHR*(23);
208 IF 1=39 THEN POKE 82. 11 ^POSITION IL
1
210 IF 1=59 THEH POKE 82. 19 -POSIT ION 19.
1
220 IF 1=79 THEN POKE 82.2S:pOSITIi3N 28.
1
230 NEXT I
240 POKE BASE.l^POKE BASE+4.0
250 POKE BftSE+5.65-P0KE BASE+6.155
260 POKE 82. 2 = POSITION 2.22
100 REM PROGRAM TO PRINT 1\£ IW.K^E m
r€ LIST
110 DIM ARRAt*NAME( 1 ).STRINGNAME$( 1 )
120 REM i^ T^€ BEGINNING OF THE LIST
130 ADDRESS=F€EK( ISeii'+PEEK':: 131 >:^256
140 •? CHR'^(125>;"tiAF:IABLE NAME LIST"
150 REM iIT CHARACTER AND TEST FOR; EfCi
160 A=PEEK( ADDRESS): IF A=y THEN EhCi
170 REM PRIHT CHARACTER
180 IF A<128 THEN ? CHRtCA); ^GOTO 210
190 ? CHR$<A-128>
200 REM ST f-eJ ADDRESS AND REPEAT
210 A[)ORESS=ADDRESS+M30TO 166
1 REM DIMEhtSIW THE DUMTW STRIW:
2 DIM DUrt1V$< 1 >
3 REM DIMENSION THE ARRAYS AND STRINGS
34
Beyond The Basics
4 REM WHICH WILL NEED CLEARDC
5 DIM Al(i>.A2(l)
6 CLR -REM aEAR THE UARIABLES
7 H=3--REM # OF i^iARIAH-ES JUST DirEMSIOhE
D
8 REM IHCLUOIhC DUttfi'$
9 REM YOUR PRCGRAM MAY BEGIN HERE
100 REM HERE IS AN EXAMPLE OF HOti TO
lie REM IJSE Tl€ UhCiirCWSIOH ROUTI[€
120 DIM TEST$(20> = TEST$="rM STILL HERE"
130 DIM DUmY$(l).Hl( 50,16)
140 Al(50.18)=l^? Al(5y,10)..TEST$
150 FBI EXECUTE UHDIMEHSIOH ROIJTIf€
160 LI^£=178^0DTC! 1028
170 DIM D!Jftff$(l).A2(500>
180 A2(500>=2^-^ r2( 500 >.. TEST $
190 END
2m REM
1000 REM l.MJIMENSIDH FflUTI^E
1010 REM SAUE aj;:REt-lT FlUr-^TER iinLiJES
1620 S13G=PEEK( 13b ) : 5137=PEEK( 137 )
1036 Si40=pLEK< 140) : 3141 =PEEK( 141 )
1040 REM fWE Effi OF UhPIhBLES
1050 T1=PEEK( 134)+8:^-N ■■ T2=PEEK:( 135 )
1060 IF Tl>255 THEN T2=T2+Ml-Tl-25b
1070 POKE 13b. Tl^ POKE 137,12
10F:0 REM rWt BEGIHHIHG OF hPRhYS
1 090 T2= I WV: hDP( Dunrrr $ ). -256 )
1 100 T1=hDR( DUfflY* )-T 2:^25b
1110 POKE 148. Tr POKE 141. .12
1120 CLR ^REM CLEAR Th£ ARRAYS
1130 RO-1 RESTORE PQI^JTERS AND PETURH
1140 POKE 13b, S13b^ POKE 137,Si37
1150 POKE 140, S148^ POKE 141,0141
llbO GOTO LINE
35
Beyond The Basics
Atari BASIC Structure
W. A. Bell
By now you probably have had your Atari® Computer for a few
months, and have had a chance to put in some fairly large programs
and tinker with and embellish them. You may have even written
some programs of that type. If so, then you have undoubtedly
wished for a renumber command. In fact, if you have used BASIC
on other systems, then you have probably roundly cursed those
programmers who left that facility out. Or you may have wanted to
change the name of a variable to make it more self-documenting,
but didn't know everywhere it occurred. This article will explore, in
tutorial fashion, the structure of Atari BASIC programs as they are
stored in memory. It will provide you some tools for doing more of
your own exploring, and then show how you can put this type of
information to use.
To begin our exploration inside BASIC, the program shown in
Listing 1 is useful. It lets us peek around in memory to find things
that are of interest. It will search memory from a specified starting
address and tell you where it finds a string of characters or data you
have specified, or it will find address pointers to a specified memory
location. It will also let you dump memory in two formats, decimal
or hexadecimal, and character. If your Atari is plugged in, it may
help your understanding to follow along on your keyboard.
Do the following steps in direct mode;
NEW
TESTVAR 1 = 999
TESTVAR2 = 123456
TESTVAR3 = 98765432
Now enter the memory analysis utility program in Listing 1 (you
may want to save it for future investigations). As an initial
objective, let's try to find the following:
• Where the BASIC statements are stored
• Where variable names are stored
• Where variable values are stored
Let's start our search by seeing if we can find where the actual lines
of the program are stored in memory. To do that, we RUN the
memory analysis utility program, and request that it find the
character string in the first REM statement (Line 10). To do that
specify "S" for function required and enter the characer search
mode by responding with a "C". Then enter the character string
36
Beyond The Basics
"MEMORY ANALYSIS UTILITY." Be sure to request the dump in
decimal this time. After the appropriate pause, a match should be
found at address 2264 and you should see the first lines of comment.
At this point it should be explained that the article assumes
throughout that you have a system without disk. For those of you
with disk systems most of the addresses will be different, and there
may be some variation in some of the commands, but the
fundamental concepts remain the same. If you have trouble
reproducing these results with a cassette system, it probably is
because of differences in the sequence in which the program was
entered, or errors in variable names. To resolve this you can do a
LIST "C, a hlEW, enter the variables again in direct mode, and do
an ENTER "C.
Examining this more carefully, you will note that there are a
few bytes in between the comments of each of the REM lines. After
some study, you may note that the line numbers appear to start five
bytes before each comment, at addresses 2259, 2288, etc. At this
point you may wish to request another search, again with a decimal
dump, looking for the character string "A DUMMY LINE" as listed
in Line 256. The search will find a match at address 2847, and you
will find that the value at address 2342 is now zero, but the next
byte now has a value of one, where it previously was always zero. In
fact the line number occupies two bytes, with the low order byte
containing the low order bits, and the higher byte containing the
high order eight bits. Thus the line number is 256 times the second
byte plus the first byte, or 256*1 +0 = 256. All binary 16'bit numbers
in the Atari (and most 6502 processors) are stored in this fashion,
including addresses. You may want to study lines 650 through 700
of Listing 1 to see how this type of number is manipulated.
To understand a little more of how this structure is laid out, try
adding the following line to Listing 1.
IREM
Now request the dump function starting at address 2259. You will
see that we now have Line Number one, followed by five bytes, and
then Line Number 10. Looking at the Line one dump, we see the
first two bytes represent the line number, while the next two bytes
contain the value six. Byte number five contains a zero, and byte
number six contains a 155, which from Apendix C of the Atari
Basic Reference Manual is a RETURN or EOL character. You will
37
Beyond The Basics
note that the rest of the REM statements follow a similar format.
In fact we can now deduce that the third byte gives the length
of the lines in bytes and by adding that to the address of the present
line, we can find the next line. (Let's reserve study of the fourth byte
until later). Similarly we can deduce that the fifth byte contains the
equivalent of an opcode for the REM statement, while the EOL
character signifies the end of the character string following the
REM. This also conforms to the information in Chapter 11 of the
BASIC Reference Manual under Item 2, where it states that each
logical line requires six bytes of overhead.
With these facts in hand, let's leave the subject of BASIC
statements for a moment, and see what we can observe about the
other things we want to find.
Note that the second and third items are alluded to in the
BASIC Reference Manual in Chapter 11, Item 3. The statement is
made that a variable takes eight bytes plus the number of characters
in the variable name the first time it is used, but that each
subsequent reference takes only one byte. Thus the variable name
and value cannot be stored in the BASIC statement.
Let's start the search for variable names by looking for the
variable TESTVARl that we entered before we keyed in Listing 1.
After typing RUN, specify a string search for the characters
"TESTVAR." With an appropriate wait for the computer to find it,
it should respond with an address of 2048 (decimal), and a dump of
the surrounding area.
Examining the dump received, you will see the characters
TESTVARl starting at the indicated address. However, note that
the last character is in inverse video, or more precisely, that the
high bit of the last character in the name has been set to a one.
Following TESTVARl, you will see the variable names TESTVAR2
and TESTVAR3, each with the last character in inverse video. You
will also see the variables used in the program displayed in the same
manner, each with the last character in inverse video.
Now specify an address pointer search for the address where
the variable name table was found (2048). In this case several will
probably be found, but the one of interest is the one found on
memory Page at address 130 and 131. (For those of you not
familiar with the 6502 architecture and the significance of Page 0,
you may want to refer to one of the excellent references on this
subject.) One more problem with the variable name table remains.
Since it is of variable length, depending on how many variables
have been defined, and the length of each variable name, how do
38
Beyond The Basics
we know where the table ends?
A little deductive reasoning is in order. Remember that
variables can only contain alphanumeric characters. Thus any non-
alphanumeric character could be used as a flag for the end of the
variable table. Looking at a dump starting at 2048, sure enough
after the variable BYTEO we see the value (address 2122). Now
doing an address pointer search for address 2122, we find such a
pointer at 132 and 133 on memory Page 0. We can also do a search
for an address pointer to the beginning of the program lines by
specifying a search for an address pointer to address 2259 where we
found the first line of the program. Again a reference will be found
on Page 0, this time at address 136 and 137.
Let's review what we found so far. We have a variable name
table stored from address 2048 to 2122, with a pointer to the
beginning of the table stored at addresses 130 and 131, and a
pointer to the end of the table at 132 and 133. We also have the
program lines stored beginning at address 2259, and an address
pointer at 136 and 137. So what do you suppose is stored in
between the end of the variable name table and the beginning of the
program lines?
To find out, let's do a dump starting with the byte after the
end of the variable name table, or address 2123, in decimal. After
doing so, nothing much jumps out at you — right! So let's try a
dump in hex starting at the same address. This time, with some
study you will find in order the hex characters 09 99, 12 34 56, and
98 76 54 32 interspersed with other data. Looks like we may have
found the variable value table, doesn't it?
Let's study this dump a little closer. Looking at the other
bytes, and remembering what Chapter 1 1 said about 8 bytes per
variable, study the value of TESTVARl. What you should see is:
00 00 41 09 99 00 00 00
Similarly for TESTVAR2 and TESTVAR3 we see:
00 01 42 12 34 56 00 00 and
00 02 43 98 76 54 32 00
Thus the structure of the variable value is such that it is stored in
binary coded decimal (BCD) as a floating point number. The digits
are stored left -justified in bytes four through eight of the 8-byte
block, with the exponent stored in byte three. The exponent is
defined such that for numbers greater than one, the exponent is
from hex 40 to hex 7F, while for numbers less than one it will have
a value from 00 to 3F. For negative numbers the high order bit will
39
Beyond The Basics
be set to one, or the exponent will range from 80 to FF. At this
point you may want to end the dump program, change line 50 to
assign a different set of values to the three variables, and then run a
dump of this same area to see the changes.
Now that you have convinced yourself of the way numbers are
stored, we still have a mystery or two to solve. What about byte
two? Suppose that might be the variable number? Remember the
statement in Chapter 1 1 about how additional references of a
variable only take one byte. Seems that the only way to do that
would be to assign a variable number. Also note that you are
allowed a maximum of 127 different variables in a given BASIC
program (see Chapter 1 of the Reference Manual). So the deduction
that byte two of the 8-byte block is the variable number seems
logical. Furthermore it gives a method of finding the variable name
for such purposes as listing the program or operating in the direct
mode.
Let's leave the use of the high order bit of byte two and the use
of byte one of the 8'byte block to your investigation, with a couple
of hints. Try examining the variables A$, B$ and HEX$. You may
also want to define a numeric array in the direct mode and assign a
set of values to it, and then dump its 8-byte block. One final step in
this investigation is to try to find an address pointer to the variable
value table. Specify a pointer to the address 2123, and we find that
such an address pointer exists at 134 and 135 on Page of memory.
Let's stop and summarize what we have learned at this point.
FIGURE I is a visual depiction of the layout in memory of the
address pointers on memory Page 0, the variable name table, the
variable value table, and the program storage area.
At this point let's set our objective to create a full featured
renumber utility. We have the fundamental information regarding
memory layout and usage. The only additional data needed is to
determine how line numbers are used in a program line. To
investigate this, LISTING 2 has been developed. You can enter it at
this point, either clearing the old program out, or leaving it at your
option (if you have adequate memory).
The program in Listing 2 has been designed to let us dump a
specific BASIC line. It will give us a decimal, hex, and character
dump of any line we want. To digress for a moment, what we will
get is a picture of the tokenized version of the BASIC line. This is
the form used to store a program in the save mode. The list mode
on the other hand stores the program just as you see it when you do
40
Beyond The Basics
a list to the screen or printer. Also note that a save operation will
save the variable name table and the variable value table as well.
The intention is to decipher the internal structure of a BASIC
line; since we want to generate a renumber utility, more specifically
we want to see what those lines with line number references look
like. Let's start with one of the most common line referencing
statements, the GOTO. When the program in Listing 2 has been
entered, add the line
10 GOTO 10
Then in direct mode type
GOTO 20000
Now request that the program find and dump Line 10. What you
will see as a dump is:
DEC
10
13
13
10
14
64
16
HEX
OA
00
OD
OD
OA
OE
40
10
00
00
DEC
22
HEX
00
00
16
Now change Line 10 to read
10 GOTO 123456
and with another GOTO 20000, the dump will read:
DEC 10 13 13 10 14 66 18 52 86
HEX OA 00 OD OD OA OE 42 12 34 56
DEC 22
HEX 00 00 16
From the change that takes place, it is obvious that the referenced
line number is stored in bytes seven through 12 of the line. Not
only that, but also it is stored in exactly the same format as variable
values are stored. You may want to try a few other values for the
referenced line number to convince yourself.
We can also speculate that the opcode for the GOTO must be
either byte five or byte six, or a combination of the two. Now let's
see how BASIC lines with multiple statements are formatted. Again
modify Line 10 as follows:
10 GOTO 999:GOTO 999:GOTO 999
and doing a GOTO 20000 we get the following dump:
DEC 10 33 13 10 14 65 9 153
HEX OA GO 21 OD OA OE 41 09 99 00
DEC 20 23 10 14 65 9 153
HEX 00 00 14 17 OA OE 41 09 99 00
41
Beyond The Basics
DEC
20
33
10
14
65
9 153
HEX
DEC
00
00
14
22
21
OA
OE
41
09 99
00
HEX
00
00
16
From this we can conclude that bytes four, 13 and 23 are used to
describe the length of a given statement in the line. More precisely,
they are used to give the offset from the address of the line number
to the next statement, and the last of these in a multi-statement line
will always be the same as byte three of the line.
At this point we need to establish what statements use line
number references. After studying the BASIC Reference Manual,
the following types of statements can have a line number reference:
GOTO GOSUB ON ( ) GOTO ON ( ) GOSUB TRAP
LIST RESTORE IF () THEN IF () THEN GOTO
IF ( ) THEN GOSUB
Taking each of these statements in order (entering the line number
as shown, and then dumping it) we get the following results:
1
GOTO 999
DEC
1
13
13
10
14
65
9
153
HEX
01
00
OD
OD
OA
OE
41
09
00
00
DEC
22
HEX
00
00
16
2
GOSUB 999
DEC
2
13
13
12
13
65
9
153
HEX
02
00
OD
OD
OC
OE
41
09
99
00
DEC
22
HEX
00
00
16
3
ON Z GOTO 997
,998
,999
DEC
3
31
31
30
133
23
14
65
9
HEX
03
00
IF
IF
IE
85
17
OE
41
09
DEC
151
18
14
65
9
152
HEX
97
00
00
00
12
OE
41
09
98
00
DEC
18
14
65
9
153
HEX
00
00
12
OE
41
09
99
00
00
00
4
ON Z GOSUB 997, 998, 999
DEC
4
31
31
30
133
24
14
65
9
HEX
04
00
IF
IF
IE
85
18
OE
41
09
DEC
151
18
14
65
9
152
HEX
97
00
00
00
12
OE
41
09
98
00
DEC
18
14
65
9
153
HEX
00
00
12
OE
41
09
99
00
00
00
5
TRAP 999
DEC
5
13
13
13
14
65
9
153
HEX
05
00
OD
OD
OD
OE
41
09
99
00
DEC
22
HEX
00
00
16
42
Beyond The Basics
6 LIST 999
DEC 6
13
13
4
14
65
9
153
HEX 06
00
OD
OD
04
OE
41
09
99
00
DEC
22
HEX 00
00
16
7 RESTORE 999
DEC 7
13
13
35
14
65
9
153
HEX 06
00
OD
OD
04
OE
41
09
99
00
DEC
22
HEX 00
00
16
8 IF Z THEN 999
DEC 8
15
15
7
133
27
14
65
9
HEX 08
00
OF
OF
07
85
IB
OE
41
09
DEC 153
22
HEX 99
00
00
00
16
9 IF Z THEN GOTO 999
DEC 9
17
7
7
133
27
17
10
14
HEX 09
00
11
07
07
85
IB
11
OA
OE
DEC 65
9
153
22
HEX 41
09
99
00
00
00
16
10 IF Z THEN GOSUB 999
DEC 10
17
7
7
133
27
17
12
14
HEX OA
00
11
07
07
85
IB
11
OA
OE
DEC 65
9
153
22
HEX 41
09
99
00
00
00
16
From these dumps we now deduce that all line number references
are preceded by a byte having the decimal value 14. Furthermore,
the byte preceding the byte with a value of 14 will have one of the
following values if a line number reference follows:
OPCODE STATEMENT
4 LIST
10 GOTO
12 GOSUB
13 TRAP
18 ON ( ) 2nd, 3rd, etc. line references
23 ON ( ) 1st line reference
24 ON ( ) GOSUB 1st line reference
27 IF ( ) THEN
35 RESTORE
In fact, it appears that the actual usage of the value 14 in a BASIC
statement is to indicate that a BCD floating point constant follows.
To see this, you may want to reload the program in Listing 1 and
search for the decimal value 14. You should find that any
occurrences in the program storage area, aside from line or
statement lengths, precede a numeric constant.
With this information in hand, we now know enough to
construct a Renumber utility. The basic algorithm is as follows:
I — Find each line number reference
43
Beyond The Basics
2 — Find the line that is referenced, and count the number of
lines from the beginning
3 — Compute what the new line number will be
4 — Store that value as the new referenced line number
5 — When all line references have been set to their new value
then do the actual renumbering of lines.
There remains a sticky implementation problem, since line numbers
are stored as floating point numbers. (Why this approach was
chosen by Atari remains a mystery — a binary format would have
required two bytes instead of six, and no internal conversion.)
Listing 3 demonstrates one technique for solving this problem, using
the variable value table we found earlier. In this case, the location of
the value for a specific variable (REFLINE) is established. That
varible is used to store the new referenced line number when it is
computed. Then that value is POKEd into the location for the line
number reference.
Other more elegant solutions, requiring fewer statements, are
possible, but they generally require some additional exploration of
the structure of BASIC. At this point you will probably want to
study Listing 3 along with its comments, and then enter it into your
Atari. You should also note that this implementation of a renumber
utility is not capable of renumbering itself. One other limitation is
that the program will not deal with situations where variables are
used as the line number reference. In such cases, you will have to
follow the computational routines used to set the value of the line
number reference, and either alter them appropriately, or else
restore those line numbers to their original value after renumber has
done its thing.
So how is such a program used? After the program has been
entered, ready the tape recorder and, in the direct mode, type;
LIST "C
This will store the renumber utility on tape in a form so that it can
be merged with other programs already in memory. (A CSAVE
would be advisable, just for backup purposes.) First CLOAD a
program you want to test the utility on. When that has finished,
position the tape at the location where you started the List "C, and
type:
ENTER "C
When the renumber utility has been loaded, a list command will
show that it has been merged in at the end of the program
previously loaded.
44
Beyond The Basics
Now type GOTO 3200 and watch the results. One more step
of course, is saving the program once it has been renumbered. If you
simply do a CSAVE, you will also store the renumber utility with
your original program. To avoid doing that, (gobbling up all that
precious memory, not to mention space on your tape) do the
following:
LIST "CI ",0,3 1999
Rewind the tape to where the list started and
ENTER "C
You now have just the original program in its renumbered form,
and it can be CSAVEd in the conventional manner.
We have been able to develop a utility to renumber BASIC
programs using the information we have uncovered. We have also
found several techniques for conserving memory, such as not using
the IF THEN GOTO statement, as it uses two more bytes than IF
THEN. Using a variable will also save over using a constant if it is
used more than twice. And, of course, every statement put into a
multiple statement line saves three bytes. There are several other
functions that could be implemented: such as changing variable
names; finding all references to a given variable; the deletion of
blocks of lines; and renumbering selected lines of a program. Some
of these ideas require additional digging tci find all of the data
necessary; others can be implemented with the things we know at
this point.
Two problems exist at this point. The first is that utilizes such
as that in Listing 3 require a good deal of memory — a precious
commoc^ity for most of us. The second is that, for programs of any
significant size, the use of such a utility will take a considerable
period of time. A future article will take what has been developed to
date anci convert some of the more complex functions to machine
language subroutines. These subroutines will be general purpose in
nature, so that they can also be used in implementing some of the
functions in the previous paragraph. Happy PEEKing!
45
Beyond The Basics
FIGURE 1
Memory Layout for
Atari Basic Tables
Page — Address Pointers
130, 131
Variable Name Table, Beginning
132, 132
Variable Name Table, End
134, 135
Variable Value Table, Beginning
136, 137
First BASIC Line
Variable Name Table
FIRST NAME | High bit on, last byte
SECOND NAME | Hiwh bit on, Ust byte
LAST NAME | Higb bit on, last byte
Variable \'alue Table
Undefined
Undefined
BASIC Lines
Variable ^
\'ariable ^
Exponent
Exponent
BCD Number, 5 bytes
BCD Number, 5 bytes
Line '
Line /'
Line ?
Line e
Offset to next line
Offset to next line
46
Beyond The Basics
Program
•10 REM MEMORY ANALYSIS UTILITY
-20 REM by W. A. Bell May 198]
30 REM " Englewood, Colorado "
AO DIM A$(100),BS(1 ),HEXS(16)
50 HEXS="0123A56789ABCDEF"
60 TESTVAR1=999:TESTVAR2=123A56:TESTVAR3=98765A32
70 PRINT CHRSf 125.)
90 PRINT "
MEMORY ANALYSIS UTILITY"
100 PRINT
"ENTER
S FOR DATA SEARCH"
1 10 PRINT
"
D FOR MEMORY DUMP"
120 PRINT
"
A FOR ADDRESS POINTER SEARCH"
130 PRINT
E TO END"
140 INPUT
B$
150 IF BS=
"S" THEN
210
160 IF BS=
"D" THEN
770
170 IF BS=
"A" THEN
630
180 IF B$=
"E" THEN
END
190 GOSUB 1270: GOTO 100
210 PRINT "ENTER C FOR CHARACTER DATA"
220 PRINT " D FOR DECIMAL DATA"
230 INPUT B$
240 IF BS="C" THEN 360
250 IF B$="D" THEN 270
--256 REM A DUMMY LINE
260 GOSUB 1270:GOTO 210
270 PRINT "ENTER DECIMAL DATA TO SEARCH FOR'
280 PRINT "IN THE FORM D 1 , D2 Dn"
290 PRINT "END WITH A VALUE OF 999"
300 ALENGTH=0
310 INPUT I
320 IF I>255 THEN 390
330 ALENGTH=ALENGTH+1
340 A$(ALENGTH,ALENGTH) = CHR$( 1}
350 GOTO 310
360 PRINT "ENTER CHAR STRING TO SEARCH FOR"
370 INPUT A$
380 ALENGTH=LEN(AS)
390 GOSUB 1200
400 GOSUB 1 170
410 POKE 1408,0
420 FOR 1=0 TO 4000
430 IF PEEK(I)<>ASC(A$(1 , 1 )) THEN 590
440 IF ALENGTH<2 THEN 490
450 FOR K=2 TO ALENGTH
460 IF PEEK(I+K-1 )<>ASC(A$(K,K) ) THEN 590
470 NEXT K
490 PRINT CHRS( 125); "MATCH AT ADDRESS = ";I
500 POSITION 28,0:PRINT CHRS( 1 38 ) ; CHR$( 1 36 )
510 PRINT "DUMP STARTS AT ";I-7
520 FOR K=I-7 TO 1+83 STEP 10
530 GOSUB 920
540 NEXT K
550 PRINT "ENTER C TO CONTINUE SEARCH"
560 PRINT " RETURN TO QUIT";
570 INPUT BS
580 IF B$<>"C" THEN 90
590 NEXT I
47
Beyond The Basics
600 PRINT " DATA NOT FOUND _"
610 GOTO 90
630 PRINT "ENTER ADDRESS POINTER TO SEARCH FOR"
6A0 INPUT ADDRESS
650 K=0;BYTEI=INT(ADDRESS/256)
660 BYTE0=ADDRESS-256"BYTE1
670 GOSUB 1 170
680 FOR 1=0 TO 4000
690 IF PEEK(I)<>BYTE0 THEN 730
700 IF PEEK(I + 1 )<>BYTE1 TEHN 730
710 PRINT "POINTER MATCH AT ";I;",":I+1
720 PRINT "LOOKING FOR OTHERS"
730 NEXT I
7A0 PRINT "NONE FOUND"
750 GOTO 90
770 PRINT "ENTER STARTING ADDRESS FOR DUMP"
780 INPUT ADDRESS
790 GOSUB 1200
800 PRINT CHR$( 1251; "DUMP STARTS AT "; ADDRESS
810 FOR K=ADDRESS TO ADDRESS+90 STEP 10
820 GOSUB 920
830 NEXT K
SAO PRINT "ENTER C TO CONTINUE DUMP"
850 PRINT " RETURN TO QUIT";
860 INPUT B$
870 IF BS<>"C" THEN 90
880 ADDRESS=ADDRESS+91
890 GOTO 800
900 END
920 IF DUMP=0 THEN PRINT "DEC " ; : GOTO 9A0
930 PRINT "HEX ";
9A0 FOR J=0 TO 9
950 DEC=PEEK(K+J)
960 IF DUMP=0 THEN 1020
980 HEXl =INT( DEC/ 1 6 ) :HEXO=DEC- 1 6 "HEX 1
990 PRINT HEX$(HEX1 + 1 ,HEX1 + 1 );HEXS(HEX0+1 ,HEX0+1);" "
1000 GOTO 1050
1020 IF DEC<10 THEN PRINT DEC;" ";:GOTO 1050
1030 IF DEC<100 THEN PRINT DEC;" ";:GOTO 1050
1OA0 PRINT DEC;
1050 NEXT J
1060 PRINT :PRINT "CHAR ";
1070 FOR J=0 TO 9
1080 DEC=PEEK(K+J)
1100 IF (DE026 AND DEC<32 ) OR (DE0124 AND DEC<128)
THEN PRINT "_ ";:GOT0 1130
1110 IF (DE015A AND DEC<160) OR DE0252
THEN PRINT "_ ";:GOTO 1130
I 120 PRINT CHRS(DEC);" ";
1 130 NEXT J
1 140 PRINT
1 150 RETURN
1170 PRINT " patience - this may take a while"
1 180 RETURN
1200 PRINT "ENTER H FOR HEX DUMP"
1210 PRINT " D FOR DECIMAL DUMP"
1220 INPUT B$
1230 IF BS="H" THEN DUMP= 1 :RETURN
1240 IF BS="D" THEN DUMP=0 iRETURN
1250 GOSUB 1270: GOTO 1200
48
Beyond The Basics
1270 PRINT '■
1280 RETURN
INPUT ERROR
Comments for Program 1
General
The underscore {_) is used to indicate that
characters are to be entered in inverse video
Lines
60
90-190
210-610
210-260
270-350
360-380
A10
420-590
A90-540
630-750
650-660
680-730
770-890
810-830
920-1280
920-1 150
950-1050
980-1000
1020-1040
1050-1 130
I 100-1 1 10
1 170-1 180
1200-1250
1270-1280
Comments
Required since
Determine the £
Search memory f
Determine if da
Input of decima
Input of charac
Required to pre
Actual search o
Match was found
Search for an a
Convert to inte
Conduct the sea
low order byte,
Dump specified
Dump a full scr
Subroutines
Subroutine to d
Dump one line (
Hex dump after
Decimal dump wi
One line of cha
Check for curso
inverse video s
Subroutine to p
Subroutine to d
Subroutine for
a RUN command resets all variables to zero
unction to be performed
or specified data
ta input as character or decimal
1 data
ter data
vent match on BASIC input buffer
f memory
dump memory at that point
ddress pointer
rnal address format
rch, noting that addresses are stored
then high order byte
area of memory
een of memory
ump memory
10 bytes) in hex or decimal
con%'erting to hex
th appropriate spacing
racter dump for same memory
r control characters and substitute
pace
rint patience message
etermine if dump is in hex or decimal
input error
Program 2.
■ 20000 REM BASIC LINE DUMP UTILITY
■20100 REM by W. A. Bell May 1981
■20200 REM ■•'■■ Englewood, Colorado "
20300 CLR :DIM HEXS( 1 6 ) ,QS( 1 )
20400 HEXS="0123456789ABCDEF"
20500 LINEADR=PEEK( 1 36 )+256 "PEEK( 137)
20600 PRINT "ENTER LINE NUMBER TO BE DUMPED" ;: INPUT LINENUM
20700 TH1SLINE=PEEK(LINEADR)+256"PEEK(LINEADR+1 )
20800 IF THISLINE>LINENUM THEN PRINT "LINE DOESN'T EXIST -
TRY ANOTHER": GOTO 20500
20900 IF THISLINE=LINENUN THEN 21300
21000 LINEADR=LINEADR+PEEK(LINEADR+2)
21 100 GOTO 20700
21300 PRINT CHRS(I25):"LINE // ";THISLINE;" START ADDRESS = "
;LINEADR
21400 LIST LINENUM
21500 Z=10:Y=5:MAXADR=LINEADR+PEEK(LlNEADR+2)
21600 IF LINEADR+Z>MAXADR THEN Z=MAXADR-LINEADR
21700 FOR 1=0 TO Z-1
Beyond The Basics
21800 POSITION 2,Y
21900 PRINT "DEC"
22000 PRINT "HEX"
22100 PRINT "CHAR"
22400 Q=PEEK(LINEADR+I) :X=3"I+8
22500 QS=CHRS(Q)
22600 HEX 1 =INT(Q/ 1 6 ) : HEX0=Q- 1 6''HEX 1
22700 POSITION X,Y
22800 PRINT Q
22900 POSITION X,Y+1
23000 PRINT HEXS(HEX1 + 1 ,HEXl + r);HEX$(HEX0+1 ,HEX0+1 )
23100 POSITION X,Y+2
23200 PRINT Q$
23300 NEXT I
23400 LINEADR=LINEADR+Z:Y=Y+3
23500 IF y<21 THEN 23900
23600 PRINT "ENTER RETURN FOR NEXT PAGE";
23700 INPUT Q$
23800 PRINT CHR$(1 25) ; "DUMP CONTINUES AT ADDRESS ";
LINEADR:Y=2
23900 IF LINEADR<MAXADR THEN 21600
24000 PRINT "ENTER C TO DUMP MORE LINES"
24100 PRINT " RETURN TO QUIT";
24200 INPUT Q$
24300 IF Q$="C" THEN 20500
24400 END
Comments for Program 2.
General The underscore (_) is used to indicate that
characters are to be entered in inverse video
Lines Comments
20400 Constants used in hex conversion
20500-21100 Find the line the dump was requested for
20500 Find starting address of first line
20700 Compute line number of current line
21000 Compute address of next line
21300-21400 Set up to dump line
21500-23500 Dump one screen of memory
21500 Z is how many bytes to dump on this line
'Y is vertical position on screen
MAXADR is start of next line
21700-23300 Dump Z bytes of memory
22700-22800 Dump byte in decimal
22900-23000 Dump byte in hex
23100-23200 Print character representation of byte - using
POSITION avoids most of the problems with cursor
movement except clear screen (Q=125)
23500 Test for full screen of dump
23600-23800 For lines that exceed a full screen
23900 Check for end of line
Program 3.
32000 CLR : PRINT CHR$(125);" RENUMBER UTILITY
-32005 REM by W. A. Bell May 1981
50
Beyond The Basics
32010
32015
32025
32030
32035
32045
32050
32055
32070
32080
32090
32095
32100
32105
321 10
32120
32125
32130
32135
32140
32145
32150
32160
32165
32170
32175
32180
32185
32190
32195
32200
32205
32210
32215
32220
32225
32235
32240
32245
32255
32260
32265
32270
32275
32280
32285
32290
32300
32305
32310
32315
32325
32330
32335
32340
32345
32350
32355
125
.23,
9
24, 13,4.35,27, li
REM " Engiewood, Colorado
DIM OPCODE! 10),REFNAMES(7)
REFNAME$="REFLINE"
REFADR=PEEK( 1 30U256'-'PEEK( 131 )
REFCOUNT=0
FOR 1=1 TO 7
IF PEEK(REFADR+1-1 )<>ASC(.REFNAMES(I,1)) THEN 32090
NEXT I
REFADR = PEEK( 1 34 ) + 256'-PEEKt 1 35 ) + 8'REFC0UNT
GOTO 32120
REFCOUNT=REFCOUNT+ 1
IF REFCOUNT>127 THEN PRINT " FATAL PROGRAM ERROR ": END
REFADR=REFADR+1
IF PEEK{REFADR-1 )>127 THEN 32045
GOTO 32100
RESTORE 32
DATA 10,12
FOR 1=1 TO
READ X
0PC0DE(1)=X
NEXT 1
STARTADR=PEEK( 1 36 )-i 256'TEEK( 1 37 )
L1NEADR=STARTADR:REFL1NE=0
0LDLINE=-1 :LINECOUNT=0
NULINE=PEEK(L1NEADR)+256"PEEK(L1NEADR+1 )
IF NULINE>31999 THEN 32220
IF OLDLINE<NULINE THEN 32200
PRINT "SEQUENCE ERROR AFTER ";OLDLINE
LIST OLDLINE-1 ,OLDL1NE+10
END
LINEADR=LINEADR+PEEK(LlNEADR+2)
LINECOUNT=LINECOUNT+ 1
0LDL1NE=NUL1NE
GOTO 32170
PRINT "LINE SEQUENCE VALID"
PRINT LINECOUNT;" LINES"
PRINT "ENTER START, INCREMENT" ;: INPUT BASE,INCR
IF BASE+INCR"LINECOUNT<32000 THEN 32255
PRINT " INPUT ERROR - WILL EXCEED MAXIMUM LINE
NUMBER ALLOWED": END
LINEADR=STARTADR
NULINE=PEEK(LINEADR) + 256"PEEK(LINEADR+1 )
IF NULINE>31999 THEN 32470
LINEEND=LINEADR+PEEK(LINEADR+2)
STMTSTART=LINEADR+4
STMTEND=LINEADR+PEEK( LINEADR+3)
FOR I-STMTSTART TO STMTEND-1
IF PEEK(I)<>14 THEN 32430
FOR J=l TO 9
IF PEEK(I-1 )=0PC0DE(J) THEN 32325
NEXT J
GOTO 32430
FOR K=l TO 6
POKE REFADR+K+1 ,PEEK(I+K)
NEXT K
PRINT "LINE ";NULINE;" REFERENCES LINE ";REFLINE
IF REFLINE<32000 AND REFLINE>-1 AND REFLINE=INT( REFLINE)
THEN 32355
PRINT " GARBAGE LINE NUMBER " :GOTO 32430
OLDADR=STARTADR : REFCOUNT=0
51
Beyond The Basics
32360 OLDLINE=PEEK(OLDADR)+256"PEEK(OLDADR+l )
32365 IF OLDLINE=REFLINE THEN 32410
32370 IF OLDLINE>REFLINE THEN 32390
32375 0LDADR=0LDADR+PEEK(0LDADR+2)
32380 REFC0UNT=REFC0UNT+1
32385 GOTO 32360
32390 PRINT " ERROR - REFERENCED LINE DOESN'T EXIST'
32395 LIST NULINE
32400 GOTO 32430
32410 REFLINE=BASE+INCR"REFCOUNT
32415 FOR K=l TO 6
32420 POKE I+K, PEEK(REFADR+K+ 1)
32425 NEXT K
32430 NEXT" I
32435 STMTSTART=STMTEND+1
32440 IF STMTSTART>LINEEND THEN 32455
32445 STMTEND=LINEADR+PEEK(STMTEND)
32450 GOTO 32285
32455 LINEADR=LINEADR + PEEK( LINEADR + 2 )
32460 GOTO 32260
32470 LINEADR=STARTADR
32475 FOR 1=1 TO LINECOUNT
32480 BASE1=INT(BASE/256) :BASE0=BASE-256''BASE1
32485 POKE LINEADR.BASEO
32490 POKE LINEADR+ 1 , BASEl
32495 BASE=BASE+1NCR
32500 LINEADR=LINEADR+PEEK( LINEADR+2)
32505 NEXT I
32510 PRINT '"•"'■■ RENUMBER COMPLETE '■'•'"": END
Comments for Program 3
General
The underscore (_) is used to indicate that
characters are to be entered in inverse video
The program requires 2319 bytes of memory in this form.
To conserve memory, a number of lines could be deleted,
eliminating some displays and error checking. These
lines should be considered: 32095, 32180 through
32195, 32220, 32225, 32240, 32245, 32340 through 32350,
and 32510. Smaller gains can also be made by converting
the computation of line addresses and line numbers to
subroutines, and by using shorter variable names.
Lines Comments
32025-32110 Find the address of the variable REFLINE, used to store
the referenced line number
32030 Beginning of the variable name table
32045-32055 Is this the correct variable?
32070-32080 Yes, compute the address in the variable value table
32090-32110 No, search for the end of this variable (inverse video)
and increment the variable number
32120-32165 Initialize other variables
32120-32145 Set up the array of opcodes which use line numbers
32170-32225 Count the number of lines and check to make sure they
are in ascending order
32235-32245 Input the renumber parameters and check see if they
will exceed the first line number of this program
32260-32460 Find each line number reference, and replace with the
new line number
52
Beyond The Basics
32260-32280 Compute address of line, line number, address of end
of line, start of statement and end of statement
32285-32A30 Process each BASIC statement in the line
32290 Test for a BCD constant
32300-32310 Check for line referencing opcode
32325-32335 Store referenced line number in variable REFLINE
32345 Check for nonsense line numbers (just in case)
32355-32385 Scan program to locate referenced line
32410-32425 Referenced line found so compute what the new line
number will be and store in line
32435-32460 Check for end of line and update address pointers
accordingly
32470-32505 Now compute the new line number for each .line
and store in the first two bytes of the line
53
Beyond The Basics
Input/Output on the
Atari
Larry Isaacs
Here is much that you will want to know about dealing with files. There
is also an explaiuition of the XIO commands.
In this article, I will try to explain how to use the various BASIC
commands at your disposal to communicate with the peripheral
devices in your system. These peripheral devices include the Screen
Editor (E:), keyboard (K:), and TV Monitor (S:), all of which are
part of your machine. External devices which are currently available
include disk drives (Dl: through D4:), printer (P:), and cassette (C:).
The I/O (Input/Output) commands wc will be discussing are the
PUT, GET, PRINT, INPUT, XI05, XI07, XI09, and XIOl 1
commands. Also, the discussion will be limited to the use of these
commands as it relates to logical files.
Before we get into details, there are two important facts to
remember. The first one is that these I/O commands result in the
transfer of one or more bytes of data, and that, often, these bytes
will be ATASCII characters. The second fact is that the byte or
bytes which get transferred will be the same regardless of the device
with which you are communicating.
Open And Close
Before you can communicate with a peripheral device, it must first
be "opened," and, in the case of the disk, a file name provided. The
syntax of the open command is as follows:
OPEN #iocb,mode,0,"device:name.ext"
iocb - I/O Control Block through which BASIC will send its
requests to the I/O software.
mode - This should be an arithmetic expressicin which evaluates to
4, 6, 8, 9, or 12. For now we will just be using 4, 8, and 12. Their
meaning is as follows:
4 = open for reading
8 = open for writing
12 = open for reading and writing
device - This should be a letter which identifies which device to
associate with the I/O Control Block specified previously.
54
Beyond The Basics
name - This should be a name of up to eight alphanumeric
characters, the first of which must be a letter.
ext - This is an extension to the name which is usually used to
indicate the type of file, BASIC program, data, etc. It may include
up to three alphanumeric characters. The name plus extension form
the file name which is needed when communicating with the disk.
Once you have opened a device, you communicate with that device
using the "iocb" number. To close a device or file, you use the
CLOSE command. The syntax for this command is as follows:
CLOSE #iocb
Only one device can be associated with an IOCB at a time. If you
wish to associate a new drive with an IOCB that is currently in use,
you must close the old device first. In the case of the disk, cassette,
and the printer, a CLOSE command may be required for proper
operation. For example, the disk can only write groups of 128 bytes,
called sectors, which are written once enough data has been
received to fill the sector. The CLOSE command is recjuired to
cause the last sector of a file, which is only partially filled with data,
to be written to the disk. The cassette also needs a CLOSE
command to write the last group of bytes. And since the printer
doesn't print a line until an EOL (End of Line) character is received,
a CLOSE may be needed to print out the last line.
If a program terminates without error, or via an END
statement, all open devices and files will be closed automatically. If
the program terminates because of an error, a STOP statement, or
the BREAK key being struck, the devices and files will be left open.
If you aren't able to continue the program, you may close the
devices and files by entering the necessary CLOSE commands
directly, i.e. without line numbers. Also, executing the RUN
command will close any open devices or files.
Now we will begin our discussion of the I/O commands. Many
of the examples make use of the disk. If you wish to use cassette
instead, simply change the file specification in the OPEN commands
to the cassette device. Just place a blank cassette in the cassette
player. Then whenever you hear two beeps, rewind the tape, press
PLAY and RECORD on the player, then hit RETURN on the
ATARI. Whenever you near one beep, rewind the tape, press PLAY
on the player, then hit RETURN on the ATARI.
Put And Get
Let's look first at the PUT and GET commands, which are the most
basic of the I/O commands. These two commands result in the
55
Beyond The Basics
transfer of a single byte, with the PUT command sending a byte,
and the GET command recei\'ing a byte. Here is the syntax for the
commands:
GET #fn, variable where "fn" is a file number, and "variable" is a
simple variable, not an array or string variable
PUT #fn, expression where "expression" is an arithmetic
expression
Listing 1 pro\'ides an example for using the GET and PUT
ccTmmands. In this program the Screen device is opened for reading
and writing. This open command will also cause the screen to be
cleared. The letters from "A" to "Z" are sent to the Screen using the
PUT command ancH, after the cursor is repositioned, the letters are
fetched back from the Screen using the GET command.
Program 1
18 DIM T$<30>
28 OPEN #1.12.0."S^''^REri iDPEN FOR: R/W
38 FOR I=ASC("A"> TO ASCx "2" >
48 FUT #L^^EXT I
58 F-OSITICiN FtEK<82>,y
68 FOR 1=1 TO 26 = GET #LCHAF:ACTER
78 TK I .. I >=CHR$( CHAR'ACTER >
88 ^€>;t I
90 GET ttLTREM tlOCE CllF"3rtR; p-AST T^£ Z
100 aosE #1
110 F15INT =Pf:INT T$
Listing 2 provides a similar example which communicates with
a ciisk. Note, if you run this program a second time, opening the file
for writing will cause the old file to be deleted. Also, if you try to get
more bytes than were written to the file, an ERROR 136 (End of
File encountered) will be given. Changing the 26 to 27 in line 60
will illustrate this.
Program 2
10 OPEN iL8.0. "DETEST. DAT"
20 FOR I=ASC<"A"> TO RSC< "2"
38 Firr #1,I:NEXT I
56
Beyond The Basics
40 CLOSE #1
56 OPEN il.4.0/'D:TEST.DAT"
60 FOR 1=1 TO 26
70 GET #1. CHARACTER
80 F-RIHT ;CHR$(CHHF:At:TER);
90 h€XT I
100 CLOSE #1
The advantage of using GET and PUT is that you are
controlling the transfer of individual bytes. If this isn't necessary,
you will likely find it simpler and faster to use one of the following
I/O commands. Each of these commands involves the transfer of a
string of bytes.
Print And Input
The PRINT and INPUT commands arc used to transfer a string of
characters. The syntax of these commands is as follows:
PRINT #iocb; list where the "list" is a list of expressions separated
by commas or semicolons. The expressions may be numbers, strings,
simple variables or string variables. If a semicolon is used prior to an
expression, the characters for this expressicin will be sent
immediately following any previous characters. If a comma is used
instead of a semicolon, including the one shown in the syntax,
tabbing will occur before characters from the expression are sent. If
the list doesn't end with a comma or semicolon, an EOL character
will be sent at the end of the list. If you wish, the list need ncn
contain any expressions.
INPUT #iocb, list where the "list" is a list of expressions separated
by commas. The expressions may be simple variables or string
variables.
When printing strings, naturally the characters in the string
are sent. However, when you print a number, the number is
converted to a string of cligits and sent as ATASCII characters.
When you input a string, characters will be fetched until an EOL
character is receivecT These characters will be stored in the string's
reserved memory until that is filled or the EOL character is
received. When you input a number, characters v/ill be fetched until
an EOL character or a comma is received. At this point, assuming
all the characters were valid digits, the string is converted back to a
number.
Listing 3 provides an example of using PRINT and INPUT
57
Beyond The Basics
with the Editor device. Like the Screen device, the Editor will print
and fetch characters from the screen memory. However, when
printing to the Editor, control characters will perform the associated
function instead of printing a character. When you input from the
Editor, RETURN must be hit before the Editor will begin sending
characters. Also, the Editor remembers the line and column of the
cursor when the input request is made. As long as you don't hit a
cursor-up or cursor-down, the fetching of characters will begin with
the first character of the new line which the cursor occupies. The
fetching of characters will continue until the last nonblank
character of the line occupied by the cursor when RETURN was
hit. You can explore the operation of the Editor further by making
changes to Listing 3, and finding out what happens.
Program 3
10 DIM T$';8y>
20 UPEH #1.12.0.. "E-"
30 F-RIHT #1.;"123.CHhRAi:TERS"
40 F-RINT »1.CHF;$(28); -m] m UP-CUF:SOF.:
50 IWH.it #LT$
60 fm\l #1;CHR*(28).:
70 imSl tl.hOIBER
88 CLOSE #1
90 F-RINT "11=".; T$
100 F-RIHT "NJMBER=";Nil1BER
lie REM JUST HIT RfTURH NHEl^ EACH
120 REM iDF THE DPUT STATEMENTS
130 REM EXECUTES
Listing 4 gives an example of using PRINT with the disk. The
program reads back the characters using the GET command so you
can see what was sent to the disk by the PRINT command. Again,
you can experiment with changes to this program to improve your
understanding of how these commands operate.
Program 4
10 DIM T$<10)
20 T$="AeCDEFGH"
30 OPEN #L8.0/'DaEST.DAT"
58
Beyond The Basics
48 F-RIHT tl.iT$
50 CLCSE #1
60 OPEN #L 4. a.. "DaEST.DAT"
70 FOR 1=0 TO 3
80 GET #LA
90 ? flj::H?*(A)
180 HLXT I
110 C.LO£;E tl
XI09 And XI05
The XI09 and XI05 commands, like the PRINT and INPUT
commands, send and receive a string of characters. The syntax for
these commands is as follows:
XIO ctndn,#icob,mode,0,exp
"cmdn" is the XIO command number.
9 = PUT RECORD
5 = GET RECORD
"iocb" and "mode" have the same function as in the OPEN
statement.
"exp" may be a string or string variable when writing, or a string
variable when reacfing.
The XI09, or PUT RECORD command will write characters from
the specified string until an EOL character is written. If the string
contains an EOL character, the XI09 terminates at this point, and
the rest of the string isn't written. If the string does not contain an
EOL character, one is appended. This differs from the PRINT
command where the entire string is written regardless of content.
the program in Listing 5 illustrates this difference.
Program 5
10 DIM T$<10>
20 T$="ttBC;DEFGHIJ"
30 T$(5.5>=CHF.'$(155)
40 fjm\ #1..S.0."E^"
45 ? "PRINT DOES THIS"
50 F-RINT *1.;T$
55 ? ^"^ "XIO iJOES THIS"
60 XIO 9,ti.8.0..T$
70 CLOSE #1
59
Beyond The Basics
The XI05 command, like the INPUT command, will fetch one
string and store it in memory. But where the INPUT command
stops (when the memory reserved for the string variable is filled),
the XI05 command keeps going. This means that the XI05
command can load more than one string variable. A second
difference is that the INPUT command doesn't store the EOL
character, where the XI05 command does. And one last difference,
the INPUT command will change the length of the string variable
to the number of characters stored, where the XI05 command
doesn't change the length of any string variable. Before you can
make productive use of the XI05 command, there is one more
necessary fact. Once the XI05 command fills the first string variable
to its current length, the next character fetched is apparently
discarded and the next memory location is left unchanged. This
applies only to the string variable specified in the command
statement. The program in Listing 6 illustrates the preceding
discussion.
Listing 6
10 DIM D$<nJ$(4>,Tl$(4).T2$(10>
20 OPEN #L 8. 0. "DETEST. DAT"
30 >aO 9, #1.8.0." ABCDEFGHUK"
40 CLOSE #1
50 Tl$=";<«XXXX:'<XX":REh RESET Tl$
60 Ti$="'ri'YYY":REn rw.E leni:th 5
70 OPEN #h4.0/'DaEST.DAT"
80 IhfUT #1.T2$
90 CLOSE #1
100 ? "IhfUT DOES THIS"
110 ? TZ^.LEbKTSt)
120 T2$="XXXX>i>KXXX"^R£M RESET T2*
130 T2$="'iTfv'V":RtM rlAKE LEW^TH 5
140 OPEN #1..4.0.."D TEST. DAT"
150 XIO 5..#1..4..0.T2$
160 CLttSE #1
170 ? ■■■'' "XI05 DCeS THIS"
180 ■~: T2*...LEHa2*>
190 T2$( 10.10;'="Z"
200 ? Vc%.L£W..12i-'
210 ? "mTicE THE X ISN'T mum] aER"
220 T$="XX'^X" ai$="XXXX" :T2$="XXX"
60
Beyond The Basics
236 Cf€H #1..4.«. "DETEST DhT'^
240 XIO 5.*1..4..ti.W
250 LlirSE #1
260 ? ^? "OR >art5 CAN LiO THIS"
270 ? T$:v Tl$:v T2*
XI011AndXI07
The XIOll and XI07 commands are used to write and read blocks
of 255 bytes, respectively. The syntax for these commands is the
same as for XI09 and XI05 except for the ctimmand number. The
commands transfer bytes beginning with the reserved memory of
the string variable specified in the command. Since you are
transferring bytes, their content has no effect on the operation of
the command. As with the X105 command, once the XI07
command fills the current length of the first string variable, the next
byte fetched isn't stored in memory.
Naturally the XIOl 1 and XI07 commands could be used for
handling strings of characters. However, if we knew where the
address of a string's reserved memory was kept, we could make
changes to it, and use these commands to save anci restore any
portion of memory we want. Fortunately this isn't too difficult.
Each string variable will have an entry in the variable storage area,
which contains 8 bytes of parameters for the variable. The third and
fourth bytes of the parameters contain the displacement from the
beginning of the array stcirage area to the reserved memory for that
string. If we dimensitin a string variable in the first statement of a
program, then this ciisplacement can be found by PEEK(134) +
(PEEK(135)*256) +2. Also, the address of the reserved memory for
this string will be at the beginning of the array storage area. For
more detail about this, see INSIDE ATARI BASIC and ATARI
TAPE DATA FILES in COMPUTE # 4.
Listing 7 shows how to save an array to disk and then read the
data from disk into a different array. In this program we direct the
XIO II command t:o save the desired portic^in of memory by
POKEing the recjuired displacement into the parameters of D$. We
then read the data into a different array, which could have been in
a different program, by again POKEing the necessary displacement
into the parameters of D$. Note the use of the MARK strings and
the ADR function to find where the arrays are in memory. Another
application might be to add some machine language routines tc:) a
program by reading them from disk or cassette and storing them in
Beyond The Basics
the required location in memory.
Listing 7
10 DIM D$(1"^REM DUrtry STRItC
15 RBI FIND «OR:ESS Cf DlSFLACEtlENT
26 ADClR=( PEEK< 134 >+PEEKX 135 >:'^256 ;'+2
25 Rei FIND BEG INN I m: OF ARF;AY STORAGE
38 BOA=ADR<D$)
48 DIM MARK 1$( 1 ). ARF:AY1< 86 ) . Xl$( 23>
45 REM WITH b BYTES/(hRRAV HUTIBER.
46 FS1 THIS DUeGI0H:5 515 BYTES
47 REM OR 2:^255
48 REM NOW FILL ThE hRRw'i'
50 FOR 1=0 TO 8y^HRi;;AYl(I)=I:t£^;T I
68 OPEW #L3,8;"D-TEST.DAT"
65 REM mi l*ITE THE AF:RAY IH 2 BLOCKS
70 FOR hH) TO 1
88 Trf=ADR(riAF.:Kl$)
90 rJBJB 1900
110 X.IO lL#1..8.0.[ri
120 YB^'.l M
130 CL&5E #1
140 DIM ^im:2i< 1 ■' . ARRA'f2( 89 ) . X2$( 23 )
150 iJPEH #L4.0.."DaEST.DftT"
155 REM \m READ 1\£ ARF:AY
160 FOR M=8 TO 1
170 Tri^=HDFXriARK2$)
180 GOSLie 1000
190 XIO 7.#h4.0,.D$
200 NEXT N
210 att-JE #1
220 FOR 1=0 TO 80 STEP 19
230 ? ARRAY2< I >
240 t€XT I
250 EMJ
980 REM ;5tJBF.:0UTU€ TO FIX THE
985 REM DISPLACEriEHT- h^BLOCK NlilBER
1000 TtP=TrP-B0A+(H;^255)
1010 POKE ADDR,TrF-IMT(Trf'/25fc)*25b
1820 Ft)KE ADDF:+l..IHT(TriP/25t':;'
1030 RfTURt^
62
Beyond The Basics
This concludes the explanations of the various I/O commands. I
hope I have explained them well enough for yciu to put them to
productive use. Some of the explanations are fairly brief, so to find
out more, or to better understand their operation, I highly
recommend that you do some experimenting of your own. This is
the best way to find out what the commands will do in specific
situations.
63
Beyond The Basics
Why Machine Languase?
Jim Butterfield
Here is an overview of several important aspects of machine langnaf^e.
BASIC programmers soon discover that their machines have an
"inner code." Somewhere inside, there seems to be another language
that is very fast, powerful, and compact. Yet there seems to be no
easy way to gain access to this feature; it's not easy to learn, and
seems to be bound up with a special kind of machine jargon.
BASIC people often stand in awe of the machine language
"gurus." They might be surprised to find that many machine
language programmers find BASIC an intimidating language. Such
people often find BASIC to be complex, poorly defined, and riddled
with obscure syntax rules. Many KIM, SYM and AIM owners are
quite nervous when they first meet BASIC — it's such a departure
from the precise and (to them) simple machine language that they
have learned.
Each language has its own advantages and disadvantages;
neither is "better." BASIC is particularly good for scientific and
business calculations, especially where a program is changed
frequently. Machine language is used where speed is vital; it tends to
be used in mechanical environments, especially for hardware
interfaces. BASIC programmers tend to be data-oriented, and
concentrate their efforts on getting information in and out.
Machine language programmers like to work with the innards of the
machine, and spend much of their time tinkering with the
mechanics. There's room for both types of activity.
Let's compare BASIC and Machine Language to get an idea
where each has advantages. Nothing in the following list is absolute:
sometimes BASIC can be as fast as machine language; sometimes
machine language can be as fast to code as BASIC. But the
comparisons are generally valid.
BASIC is easier to write and get working. You have a freedom
to change a line, insert new coding, and check out a program
that can't be. matched in Machine Language.
BASIC is easer to read. Its English-like syntax makes it
relatively easy to pick up a prc:)gram and see what it does. A
dozen lines of BASIC might require a hundred lines of
machine language (or more) to dci the same job.
64
Beyond The Basics
BASIC has splendid huilt-in capabilities. INPUT and PRINT
are very powerful; in machine language you'd need to program
the same capabilities the hard way. Other features, such as the
way BASIC handles variables, strinus, and arrays call for a lot
of machine language coding.
BASIC usually uses less memory space. Surprise! Except for
very small programs, machine langtiage will gobble up more
memory.
Machine language is fast. It's not uncommt^n for machine
language programs to run ten or more times as fast as similar
BASIC programs. Keep in mind, of course, that input and
output of data will be geared to the speed of the external
device you are working with; machine language won't get
input from the keyboard any faster than BASIC.
Machine language can get at inner mechanisms that BASIC
can't reach. BASIC is much more portable between different
machines.
So what do these comparisons tell us?
First, if BASIC can do a job, and can do it fast enough, always
use the BASIC. You'll write the program faster, and it will be easier
to change in the future.
But if you have a speed problem, or if there's something you
need to do that's beyond the capability of BASIC, then use
machine language. Remember that with machine language you will
lose flexibility and portability. But if that's what you need to do the
job, use it.
There are other reasons why it's good to know machine
language. It gives you a glimpse of the inner secrets of your
computer. Even BASIC itself is just a huge machine language
program stored in ROM. Each BASIC statement is executed by
dozens of tiny machine language instructions which decide what is .
wanted and then perform the task. If you wanted to know precisely
how a BASIC statement wcirked', you woulci ultimately have to
trace through the machine language that did the job.
It's probably best to think of BASIC and machine language as
complementary tools. Yctu can and should use them together.
BASIC can call in a machine language prc^igram when it needs it by
using a SYS command or a USR function. The machine language
ccide can return to BASIC when it's finished the job by using the
RTS code. Data can be passed back and forth between the two
languages.
65
Beyond The Basics
The result: you can have the best of both worlds. The main
part of your program will be in BASIC so that you can code it
quickly and easily. The tricky bits, where you need speed or special
functions, will be in relatively short machine language programs.
Machine language is picky and exacting. It doesn't allow you
many mistakes. If you're an impetuous programmer, you might be
happier to stay with BASIC, which is very lenient towards your
mistakes. But if you're ready to take the time, and plot, scheme,
plan, code, check, test and review — you can do some remarkable
things with machine language.
It takes precision and patience. But there's nothing to compare
with the rush you get when your machine language prc:)gram finally
works the way you planned it.
66
Beyond The Basics
POKin' Around
Charles Brannon
Perhaps one of the most useful commands in BASIC is POKE.
Why? Because POKE allows you to cJo some things that cannot be
done as easily in BASIC. I recall the earlier days of the PET, where
every time a nifty memory lc:ication was discovered, it was published
with glee — indeed, they were real "tidbits." Nowadays, however,
there are several very good memory maps that document the inner
workings of the PET quite well.
hi the Atari Basic Reference Manual, there is an appendix
entitled "Memory Locations" (Appendix I). Although it is not a
true memory map since it is incomplete, it does list some very
interesting locations.
During the execution of a program, the cursor does not
disappear. Rather, it moves with the print statements and
sometimes is left behind, cluttering up the screen with little white
squares. Fortunately, the visibility of the cursor can be zeroed out
with a simple statement: POKE 752,1. To restore the cursor, press
the BREAK key or POKE 752,0. The well-known problem of the
non-standard behavior of the Atari's GET statement has led to the
discovery of memory location 764. Here is stored the code
representing the last key pressed. This is not in ATASCIl, but is a
code used in the scanning of the keyboard. If no key has been
pressed, a value of 255 will be found here. I first found this
technique right here in COMPUTE!. In "Adding a Voice Track to
Atari Programs," the author suggested using a subroutine like this
to check if a key has been pressed:
lineno IF PEEK (764) = 255 THEN Uneno (same lineno)
lineno POKE 764,255: RETURN
The first statement waits for a key to be pressed; the second discards
that keypress by making BASIC think no key was pressed so that
the keystroke would not be printed accidentally.
An example of how POKEing can be easier to use than a
BASIC equivalent is in directly controlling the five color registers.
After all, they tcio are only mere memory locations. Locations
708-712 correspond to SETCOLOR color registers 0-4. Using the
notation SETCOLOR ciexp,acxp,aexp where acxp is an arithmetical
expression, the first number is from 0-4, so use the appropriate
memory location. Then multiply aexp number two by 16 and add
the third number to it. This gives you an integer in the range 0-255.
67
Beyond The Basics
Now just enter POKE COLR, NUMBER where COLR is the
memory location of the color register and NUMBER is that number
you obtained. Figuring out what color is already being displayed is
done in the re\'erse fashion. Get the contents of the color register
with PEEK(COLR), and assign it to some variable, say X. (e.g.
X = PEEK(COLR) ). Divide X by sixteen, throw away the fraction
using Y = INT(X), then find the luminance {ae\p#3) with L = X-
16*Y. Now you can set the color by basic with SETCOLOR
COLR-708, Y,L or you can just store the numbers so you can
meciitate on them at a later date.
Ha\'e ttm with these memciry locations, you hackers! You
beginners — step right up and add se\'eral new functions to your
repertoire!
I want to leave you one more thing to try — POKE 755,6. It's
weird! (You can get it back to normal with POKE 755,2 or by
pressing RESET.
68
Beyond The Basics
Printins to the Screen
from Machine Language
on the Atari
Larry Isaacs
If you use machine language you'll find this useful. There are two
techniques presented here: screen output and a relocating loader.
l{ you are machine language programming on the ATARI, it can be
very acivantageous to know where some of the operating system
subroutines can be found. I can prcividc you with only one at this
time, but it's one of the handier ones. This is the output subroutine
for the Editor device. It accepts the full ATASCII character set,
printing the displayable character on the screen, or executing the
control characters. To use the routine, simply load the character
into the accumulator and execute a JSR $F6A4 instruction. The
only other fact needed is that the X and Y registers aren't preserved
by this subroutine.
To illustrate the use of this subroutine, the DUMP program is
provided. This program also illustrates one way of using machine
language with BASIC. The program asks for starting and ending
addresses, which should be given in hex. Then the requested
memory is dumped on the screen by a machine language program
executed by the USR command.
Naturally, before the machine language can be executed, it
must be placed in memory. This is done by the BASIC subroutine
in statements 10200-10430. This subroutine loads machine code
found in DATA statements, which begin at line 20000 in this
program. The first thing the subroutine does is read the number of
bytes in the machine language program. It then dimensions DMY$
to length ,1 and an array called STORAGE of sufficient size to hold
the machine code.
The subroutine then starts reading the data as strings and
POKEing the appropriate code. If the string read doesn't start with a
special character ("'Y'*",'' + "," = ", or "!") then the string is assumed
to be two hex characters which are stored in the next available byte.
If the string begins with a ".", then the string is assumed to be a
comment and is ignored. If it begins with an "*", the subroutine
Beyond The Basics
assumes the rest of the string is four hex characters which form a
two byte address. This address is POKE'd low byte first, then the
high byte. If the string begins with a " + ", the rest of the string is
assumed to be four hex characters which form a two byte
displacement from the beginning location of the code. This
displacement is added to the beginning location of the code to form
a two byte address. This address is also POKE'd low byte first,
followed by high byte. If the first character is an " = ", then the rest
of the string is assumed to be a displacement as with "*". However,
once the address is computed, the current poke location plus one is
subtracted from this address to form a one byte displacement which
is POKE'd into the next location. Finally, if the first character of the
string is an "!", the subroutine stops loading machine code. The rest
of the string is assumed to be a two byte displacement as with the
"*", and the computed address is checked with the current poke
location to see if it matches. If they don't match, it's likely that
you've miscounted some bytes and that some of the displacements
given by strings starting with the "*" or " = " character are in error.
This may seem somewhat complicated, but it really makes it
fairly simple to write relocatable code. This relocatability is
necessary because you don't know where the code will be loaded
until the program is running. Relative addressed used by branch
instructions may be given as a hex byte or as an " = " followed by
the displacement from the beginning of the program. Internal
absolute addresses should be given with a " + " followed by the
displacement. And finally, external addresses can be specified by
giving two hex bytes, or by an "*" followed by the address.
Once the code is loaded, ADR(DMY$) gives the first location.
This also happens to be the entry point of the machine language
dump program. Now the dump routine can be executed by calling
for the USR function to be executed with ADR(DMY$) as its
address. This is done on line 80 of the BASIC program.
It is important to note that the dump routine can only be
executed while the BASIC program is running. Trying to execute it
by a direct command will not work because the direct command
gets inserted in between the end of the program and where the
machine code has been poked. This will cause the machine code to
be moved. Since it contained some internal absolute addressing, it
will not execute properly any more. If the code contains no internal
absolute addressing, it can be executed by a direct command.
The machine code is fairly simple, so you should be able to
understand what it is doing. Upon entry, the machine code first
70
Beyond The Basics
checks to see if the right number of parameters are present. If not,
the parameters are pulled off the stack and the program returns to
BASIC. If the correct number (2) is present, the machine code will
dump the requested memory, printing 8 bytes per line.
I hope you will find some of the techniques used in this
program useful, as well as the program itself.
1 DIM SA$(4)..EA$(4>
10 GOSUB 18200
20 F1<INT "imSl STAFlTIHG ADDRESS".;
25 INPUT Sh$
30 F-RINT "It4FiJT EtCiIM: ADDFESS".;
35 IIPUT EA$
40 l'iORD-$=SA$ M^a-AIB ISlOy
50 SA=Nl«;D
60 l-WFIt$=EAI ■ iJ^JJB 18100
70 EA=tWjFD
80 DUmV=USR( ADR( DMYI ) . S;A ■ EA )
90 GOTO 20
■ 10000 FfM CfiplJTE HBVTE FROM \€^^.i
10010 1=1^ GOSUB 10040 :tevTE=X:¥. 16
10020 I=2^G0Slje 10040 ^MEVTE=NBVTE+X
10030 F.ETURU
10840 X=ASC< HEX*( LI-' )-hSC( "0" >
10050 IF "0"<=+EX$( I .. I) AND HEX*( I .. I X="
9° 1>€H F-ETUFI^l
10060 IF "H"<=HEXt(I.. I ) A^Ci HEX*' I .: I )<>"
F" TVEH X=X-7^FfTURH
10070 STOF ^REM ERROR
10100 REM CiJfFUTE MUOFO FROM UORQ-I
10110 HEX*=l'rjRD$( 1 ,. 2 ) ■■ GOSUB 1 OOOO ■ t WORD=
101 20 HEX*=WORD*':: 3,4)^ QJSLe 1 OOOO ■ 1W0RD=
H*JRD+heVTE
10130 RETURN _
182'00 F£M F1JT THE CODE
10210 F.£AO N:R£M HUMEiER OF BYTES
1 0220 Ci I M CUE*': 40 ) . HEX*': 2 ) . WORD*( 4 ) . DfTi'
$<1 >.. STORAGE':: H.-b+D
10230 F'C=ADR'; OfTrl- >
10240 F£AD 0'££t
10245 IF CODE-ia.l '="," THEH GOTO 10240
II
Beyond The Basics
18250 IF CDOE$(l.r'="*" THEH GOTO 103yO
leif.e IF CiJOE$(l.. 1)=" + " THEN GOTO 10310
10265 IF CiJOEia; :>="=" THEN GOTO 18350
10270 IF CODE$n.l)="!" THEH GO^O 10410
10280 HEX$=CnDEfa.2)M:0sUE 10000
10290 F'01':E Fi:,lJBYTE^PC=PC+i ^GOTO 1S240
10300 WJRD*=00DE$':2.5VG0*:ilJE ImIOO-GjTO
10320
10310 WuRCi:t=CODEi< 2.5'- GOSUB 10100 ■ NUOE:
=^i»RD+ADR': DriY:J •'
10320 feVTE=IHT^ HW0R0--256 ;■
10330 F'OKE PC..NU0RD-HBVTE*25b
10340 PC=FC+1:G0T0 16290
10350 l-lJRDi=CODE*( 2,5;- GOSUE 1 01 00
10360 h«YTE=HDp. D(1V$ '+NUORn -c PC+ 1 '
10370 IF MBYTE M 27 TF€n STOP
10380 IF t-erTE':-i2y theu stop
10390 IF HBYTE(y THEN r^BYTE=HBYTE+25fc
10400 bUTu 102y0
10410 W0R0:$=r0DE$';2^5/ GOSUE 10100
10420 IF MmPD=Pi-HDP' DMYf ,' THEM PETUPfi
10430 STOP FEri ERROR
20000 OhTA 177
20010 Df-iTi-i ,000O.4C.. +0030. . Jf1F' STnF:"
20020 REM INCPNTR
20030
DhTfH
'^J03. EtT. D4.
I HO
RiTR
20040
DATri
,8805.08. =0009..
, BHt
m
20050
DATA
,3807.. EtV. 05.. .
I HO
PHTP+l
28060
F:EM '5
1
20070
DATA
8009 ..60. .
RTS
20080
REM F
RBVTE
20090
DATA
,800A. 48. .
F-HA,
20100
DATA
00OE/4ft. .
LSR
A
20110
vH : H
. -j-jyL .■ ^kj .
LSR
A
281 2'0
DATA
,880D4h. .
LSR
A
2'8138
UAlA
OOOE.. 4ft. ,
LSR
A
20140
880F,. 28.. +0015,.
. .JSR
PRM'-i-'BLE
20150
DATA
.0012., bS.. ,
FtA
28160
DATA
0813.. 29.. OF. .
Am
frlQF
28170
F:EM F
RM^yELE
28180
DATA
0015. 09, OA. .
CMF'
#$0A
20190
DATA
0017.30.=&51B.
.BMI
ii!2
72
Beyond The Basics
20200
DAT hi
.0019.. 69; 0b.. .
PLC
#$yb
20210
R'.EM 1^
2
20220
DrtlH
.0019.. 69.. 30.. .
ADC
«30
20230
DATA
.0010.20.. :^-FbA4..
,JSR
outchf:
20240
DATA
.0020.60.. .
RTS
20250
F£t1 T
STPHTR
202 Gy
DATA
.0021. .38.. .
SEC
20276
DATA
.0022.AD.. +002D..
.IDA
EA
20280
DATA
,0925..E5..D4. .
SBC
PNTR
20240
DATA
.0027.. AD.. +0y2E..
.LDh
EA+1
20300
DATA
.002h.. Ej.. D5,. .
SEC
P^^TR+1
20310
DATA
.0020.. 60.. ,
RTS
20320
m\ E
ft
20330
DATA
.002D.. 00..00.. .
.UORD
20340
P.EM r.
:rfUflT
20350
DATA
.002F.. 00.. .
. BYTE
2-0360
R£M 2
;TAF.:T
2'0370
DATA
.1-^30.63. .
F1_A
^■essQ
DATA
. 083 1.F0. =0309.
.BEQ
m
20390
DATA
.iS)33. 09.02. .
CTP
#$02
20400
DATA
.0y35..F0..=003E..
BED
CCWTIWJE
2'04 1
DATA
.0037. AA.. .
TAX
20420
F;Eri e
!3
2v3430
DATA
.0038.63. .
PLA
20440
DATA
.W39.63. .
PLA
20450
DATA
.0VJ3A. Ch. .
DEX
20460
DATA
.003B.D0.=0033..
EWE
i53
2^1465
DATA
.^3030. 60. .
RTS
20470
REM C
:OHTIHE
2'0490
DATA
.003h.68. .
F1_A
20490
DATA
.003F.85.D5. .
STA
PHTR+1
205i00
DATA
.01M1.63. .
FIA
20510
DATA
.0042. 85.. 04. .
STA
PNTR
20520
DATA
.1-^44.68. .
FIA
2f!530
DATA
.0045.8D.+9y2E.
.STA
EA+1
20540
DATA
.0048.68. .
F1_A
2'0550
DATA
.IS149.3D.+W2D.
STA
Eh
215560
REM m-f
20570
DATA
.W4C.A'9.'9E!. .
IDA
ttEOL
2'05y0
DATA
.004E.20.;>-F6A4..
. J3R
LriJTCHR
20590
DATA
.te51.A9.24.. .
IDA
#'$
2'06yy
DATA
.0053.20.:i:FeA4.
. ..!SR
OUTCHF:
73
Beyond The Basics
20610
DATA
085.6.
A5.D5. .
LDA
PHTR+1
20620
[ihTA
tesy.
i^y-.+yeeA..
. .m
PRBYTE
20630
DATA
085B,
A5.D4. ,
LDA
PHTR
213640
DATA
005D.
20;+000A..
. JSR
F'REYTE
2'0€50
DATA
8060.
A9.20.. .
LDA
r
20660
DATA
8062.
2e.:¥:F6A4..
.m
CtUTCHF'
2'0670
DATA
0065 .
A9.88. .
LDA
#$0:3
213680
DATA
0867
3D..+002F..
. STA
i:ut-WT
2'0690
REM U
Jfjp
2'0700
DAlA
tJ36A,
A9..20. .
LDA
r
20710
DATA
3860
20.:^cFtA4..
.J£;R
iJUTCW:
20720
DATA
006F
H0.08.. .
LDY
#$00
20730
DATA
iSi71
B1..D4.. .
LDA
(p^rrR)Y
2'0740
DATA
0073
20..+000A..
. JSR
PRBYTE
20750
DATA
8876;
20 ..+0803.
. JSR
IrCPbrTR
20760
UATA
6079
CE.+002F.
.ffiC
CULNT
20770
DATA
007C
D0..=kM69,.
.Br€
LOOP'
20730
DATA
ee7E
20.. +0021..
.JSR
TSTPWTR
28790
DATA
£1081
ly.=004B..
.ta
DLir-f
2'0y0y
DATA
0833
A9..9B.. .
LDA
#EUL
2'0810
DATA
3035
28,.:v;F6A4..
..JSR
OUTCHF:
28020
DATA
DATA
8033
60. .
R 1 8
2'0'930
0839
74
CHAPTER THREE
Graphics
B
Graphics
Made In The Shade:
An Introduction To
' Three-Dimensional ' '
Graphics on the Atari
Computers
David D. Thornburg
If you know anything at all about the Atari 400 and 800, you
probably know that these machines give you access to 128 colors.
What you may not realize is that these colors are specified with two
independent parameters which allow you to create "three-
dimensional" objects on the display.
The two parameters of interest are hue and luminosity. Atari
gives you access to sixteen colors (the hues), each of which can be
darkened or lightened by setting the luminance to one of eight
levels. Traditionally, computers that offer limited colors (sixteen
total, for example) pre-select different hues and luminosities for each
color so that inter-color contrast is always apparent, even when the
picture is shown on a black and white display. If two colors have the
same luminosity, you will not see any difference between the colors
when they are shown on a black and white display — a
phenomenon you should demonstrate to yourself sometime.
The beauty of the Atari scheme is that the wide range of
available colors leads to the ability to create some pretty pictures,
even though only four colors can be displayed at one time. The
program presented here illustrates a common graphics task — the
representation of a solid three-dimensional object through shading.
Since we can display three colors plus the background in a
moderate resolution graphics mode, this lets us represent a shaded
cube. After all, you can only see a maximum of three faces of a cube
at any given time. The function of the program, then, is to create a
two-dimensional representation of a cube in which the "realism"
results from the control of the shading on each visible face.
In case you are not familiar with Atari graphics, a short
digression is in order. Displayed colors are established by the
76
Graphics
SETCOLOR command which takes the form SETCOLOR A, B,
C in which A is the color register (0-4), B is the hue (0-15) and C is
the luminosity (an even number from to 14). (I don't know why
luminosity isn't set with numbers between and 7, but the use of
even numbers doesn't present too much of a problem, as you will
see.) The hues (see Table 1) are the various basic colors you can use
to draw your pictures, and the luminosities control the brightness
from (very dark) to 14 (almost white). Once you have set the color
registers, you need to indicate which register should be used for the
various plotting commands. This function is performed with the
COLOR statement. This statement has the form COLOR D in
which D refers to the color register where the desired color is
located. Now, for reasons that I don't understand, the value of D is
generally larger than the color register number by one. In other
words, D = A + 1.
Program Listing
18 F£ri n -mmmz demo
28 O^ftF-HICS 23
38 OPEH #L4..0. "Kj"
48 FOR 1=0 TO 4:SETC:rjL0R I..9.4:^e<T I
58 X0=48=Y0=36
66 CO-OR 1
70 FOR 1=8 TO 48
88 FIOT X8..Y0+I:DRAUTD X0+4y..Y0+I
90 h£XT I
1^ COLOR 2
110 FOR 1=1 TO 24
128 PLOT X8+ 1 ,. Y0- 1 ■■ DRAWTO m+ 1 +48 .. YS- 1
138 h£XT I
148 COLOR 3
150 FOR; 1=1 TO 24
160 FIOT X0+4y+LY0-I^DRAUTO X0+40+I..Y'a+
40-1
170 h£XT I
180 FOF^ 1=8 TO 2
190 GET #1.A
280 IF A<48 THEW A=48
216 SETCOLOR L 1 ; 2:*( A-48 ;'
220 h£XT I
230 GOTO 188
77
Graphics
Now that these tips on Atari color have been described, it is time to
try out the program.
The listing starts out by setting a moderately high resolution
full-frame graphics mode in statement 20. This mode allows the
display of four colors and contains 160 x 96 picture elements —
plenty for our needs. The OPEN statement lets us use a GET
statement to receive data from the keyboard without having to press
RETURN. Note that the Atari version of GET is very different
from the version you may be accustomed to from Microsoft BASIC.
Next, the color registers are all set at the same color value so that
when the cube is first drawn you cannot see it. The front face of the
cube is drawn in COLOR 1 (from SETCOLOR register 0) in lines
70-90, and the other two faces are drawn in COLOR 2 and
COLOR 3 in lines 110-130 and 150-170 respectively. At this
point, the computer waits in line 190 until a key is typed. (Note
that in Microsoft BASIC the program would not stay at a GET
command, but would look once and be on its way.) Since I expect
to be GET-ting a keystroke from keys through 7 (which have the
Atari-ASCII values 48 through 55), lines 200 and 210 convert the
keystroke Co an even number between 09 and 14 for use in the
SETCOLOR command. This program looks for three keystrokes —
one for each face of the cube. As each key is typed (try 5, 6 and 7,
for example) a cube face will become visible. The result is that a
"three-dimensional" representation of a cube is now nicely displayed
on your screen.
If you want to change the shadings, type three more numbers
between and 7 and see what happens. Next, for some more
excitement, type J, K and L. Once again you will see the shaded
cube, but the color will have changed from gold to more of a
magenta. As you can see, luminance values greater than 14 cause
the hue to change.
Now that you know about shading, you should be able to
make some truly beautiful pictures with the Atari.
Table 1. Hue Values For The Atari Computers
COLOR HUE VALUE
GRAY
LIGHT ORANGE 1
ORANGE 2
RED-ORANGE 3
PINK 4
PURPLE 5
PURPLE-BLUE 6
BLUE " 7
78
Graphics
ANOTHER BLUE
LIGHT BLUE
TURQUOISE
GREEN-BLUE
GREEN
YELLOW-GREEN
ORANGE-GREEN
LIGHT ORANGE
9
10
II
12
11
14
15
79
Graphics
The Fluid Brush
Al Baker
Picusio ivouhl luuc liked this. one'. Computers won't be replacing canvas
and paint immediately, hut nobody is placing bets on the limits of
computer graphics.
This month I got carried away. 1 had so much fun changing and
improving this program that it incorporates several hints on how to
use the Atari plus another way to use the joysticks. Before digging
into the program, though, let us see what it does.
Type in the program and run it. All but the bottom four lines
of the screen turn black. Near the center of the black area is a white
dot. Move joystick and you can paint with the dot, just as if it
were a brush dipped in white paint. The motion of the dot on the
screen is quite slow. This is intentional. If the dot moved too fast, it
would be hard tc^ control. As your skill increases, you can speed the
dot up.
Hold dou'n the joystick button and move the joystick. Now
the dcTt mo\'es much faster, but it dciesn't paint. It erases. You have
a paint brush which moves quickly from one area of the screen to
another, and yet paints slowly enough to give you complete control!
Unless you are Tom Sawyer, painting with a white brush can
be quite boring. Let's change colors. As you probably know, you
ha\'e three ccilcTr registers available in graphics mode 7. When the
program starts, you arc painting with register 1 set to white. To pick
another register, press either the I, 2, or 3 key. You are now using
this register. But before you can paint, you must choose a color.
Type in a color number between 0, for white, and 15, for light gold.
Press RETURN. Table I lists the 16 color possibilities. Now, as you
move the joystick, you are painting with this new color.
What's Going On
The program is initialized between lines 1000 and 2030. The
beginning location of the dot is position (X = 90, Y = 48); its color,
C, is 0; its color register, R, is 1; and its brightness, L, is 10.
Line 1090 opens the keyboard for input. This statment is
necessary if you want to read single ASCII characters from the
keyboard without using the INPUT statement. The number 1 is my
choice for the file number. I could have chosen anything between 1
and 5. The 4 means input, the is required, and the "K:" means the
input is from the keyboard.
Graphics
Look at Diagram 1. The joystick returns numbers between 5
and 15 depending on its position. The actual number is ued as the
subscript of arrays XD and YD to determine how the X and Y
positions of the dot on the screen are to be changed. For example, if
the joystick is pushed away from the user and to the right, the
number is 6. XD(6) is equal to 1 and YD(6) equals -1. The dot
would move one position right (+ 1) and one position up (-1) on the
screen. The arrays XD and YD are initialized in lines 1110 to 2030.
The main program loop starts at line 150. Look closely at line
160. This statement determines the speed of the dot on the screen. If
the button on joystick zero is pushed, STRIG(O) = and S will be
0. If the button isn't pressed, STRIG = 1 and S = 100. Line 170
uses the variable S as the alarm on the delay timer. Finally, lines
150 and 180 cause the dot to blink. Line 200 makes sure that if the
button is pressed, then the dot erases, or leaves a black spot, when
the joystick is moved.
The rest of the program loop is between lines 250 and 310.
Line 250 gets the value of the joystick. This value is used to modify
the X and Y positions of the dot as previously discussed. Once these
values are computed, line 290 places the dot in its new location.
The statement on line 280 keeps the dot from running off the
TV screen. If the PLOT statement tries to put the dot off the screen,
an error results. The trap on line 280 branches the computer to the
routine at line 3000. That routine adds one to Y if Y is above the
screen (Y"<0) or subtracts one from Y if Y is below the screen
(Y>79). Likewise, it adjusts X if X is to the left (X<0) or right
(X>159) of the screen. Finally, the routine jumps back to line 280 to
set the trap again and plot.
The user can type in a new register number and color. Line
300 scans the keyboard each time the program loops to see if the
artist is ready to change colors. If location 764 isn't equal to 255,
then a key has been pressed. The routine beginning on line 4000 is
called on to respond to the artist's request.
The first thing done by the keyboard routine is get the ASCII
value of the key pressed. The GET statement must use the same
number as the open statement on line 1090 and it puts the value of
the key in the variable R. The ASCII value for a one is 49 and for a
three is 51. If the key is not between these twei, it is ignored and
another is required. Once a proper key has been pressed, line 4020
converts it into the numbers 1, 2, or 3 and line 4030 sets plotting to
that color register.
The POSITION statement does not control the location of
81
Graphics
print statements in the text window when graphics mode 1 through
8 are chosen. This is done by poking values into memory locations
656 and 657. Poking a number between and 3 into location 656
will position a statement vertically on the bottom four text lines.
Poking a number between and 39 into location 657 will position a
print statement between columns and 39 horizontally on the
screen. Line 4040 positions the next print statement on the third
line of the text area at the bottom of the screen.
Since the print statement on line 4050 is always printed in the
same location, it is necessary to erase any previous answers. This is
done by including four spaces followed by four back-arrows after
the word COLOR. To insert a back-arrow, or any arrow, in a print
statement, press the ESC key before typing the arrow key.
Conclusion
I would like to thank Dick Ainsworth for his idea about using two
different speeds on the joystick to control different functions, and
I'd also like to thank William Bailey for his idea on using arrays to
simplify the conversion of joystick values into directions. If you
would like to share your ideas with other readers, send them in. If I
use them, you will also be acknowledged.
Al Baker, Programming Director, The Image Producers, Inc.
Table 1: The Atari Colors
NUMBER COLOR
Gray
Gold
Orange
Red
Pink
Violet
Purple
Light blue
MBEF
> COLOR
8
Blue
9
Gray blue
10
Turquoise
11
Olive Green
12
Green
13
Yellow green
14
Brown
15
Light gold
Diagram 1: The Joystick Control Arrays
CHANGE IN X - XD
XD(IO) = -1 XD(14) = XD(6)=1
XD(ll) = -1 XD(15) = XD(7) =1
XD(9) = -1 XD(13) = XD(5) = 1
CHANGE IN Y - YD
YD(I0 = -1 YD(14) =-1 YD(6) = -1
YD(ll) = YD(15) = YD(7) =
YD(y) = 1 YD(13) = 1 YD(5) = 1
82
Graphics
I'Z RE;"I THE FLUID BRUSH
20 PEf;
30 REM
40 REi-l GO 5ET UP CONDITIONS
£.0 G05UB 1000
120 REt'i
'.I'd REi^l GET BUTTON FOR SPEED
143 REf'^,
150 COLOR '+:PLC!T X-Y
160 5=130*5TRIG';0:'
170 FOR 1 = 1 TO 5:NE>:T I
130 COLOR RtPLOT X ? V
190 RE:-1
200 If 5=0 THEN COLOR 4 : PLOT X<Y: COLOR R
220 REt^
230 RE;\i MOVE DOT IF JOYSTICK MOVED
240 REM
250 J=5TICK(0)
2i3 Y=Y-^VD ( J .■■
270 X = X + XD':J)
290 TRAP 5000
290 PLOT X-Y
300 IF PEEK wt 4, '0255 THEN GOSUB 4000
310 GOTO 150
970 REM
930 REM SET UP CONDITIONS
990 REl'^.
1000 GRAPHICS 7
1010 X=90
1020 Y=4S
1030 C=0
1040 L=10
1050 R=l
1060 SETCOLOR R-IjCjL
1070 COLOR 1
1080 PLOT X?Y
1090 OPEN #1 ,4,0, ^^Kf •'
1 100 DIM XD( 15) ! YDC 15)
1110 FOR 1=1 TO 15
1120 READ N:XD<I)=N
1130 READ N.-YD' I)=N
1140 NEXT I
1150 RETJRN
2000 DATA 0,0,0,0,0,0,0,0
2010 DATA 1,1,1,-1,1,0,0,0
2020 DATA -1,1,-1,-1,-1,0,0,0
2030 DATA 0, 1,0,-1,0,0
83
Graphics
^lOTION
9:)
2970 REr^
29e0 REM CA
2993 PEI-I
3000 Y=Y+';Y<fl)-(Y>
3313 X = »\X<0)-(X:-
3020 G0"0 260
3970 REM
3980 REM CHANGE COLOR
3990 REM
•+000 GET #1 - R
4010 IF (R<M
4020 R=R-'+B
403S CC'LOR P.
4040 POKE i5t?2
4053 PRINT "COi_OR
4060 INPUT C
4070 SETC'.:'L.':'R R-i
4060 RETURN
"HE ECREEN
+ 1 r:-51
THEN 4330
^^^<^'
84
Graphics
Color Wheel for the Atari
Neil Harris
This program shcnvs how easy it is to get "pretty pictures" with a
minimum of coding. You might want to try the following changes:
no GRAPHICS 7 + 16
145 COLOR /NT(RNDfi)*3) + i
The Color Wheel program was written to experiment with
some of the Atari's color graphic capabilities. The screen clears
and a series of lines radiate from the center of the screen in
random colors, forming a shape with the outline of an ellipse.
As the color bands sweep the screen, the colors shift in
intensity and hue, forming a constantly changing set of
contrasts and shapes.
The program itself is quite simple, thanks to the easy
Atari BASIC graphics commancfs. Graphics mode 7 features
160 by 80 points of resolution in four colors, which are set up
in registers. One c:)f the things that made this program possible
was that you can change a cokir register value, \yhich causes
all points on the screen associateci with that register to change
cc:)lor instantly.
Line 100 selects degree mode (or trigonometric functions,
which in this case leads to less messy numbers in the FOR-
NEXT loop in line 140. Lines 120 and i 30 select values for DX
and DY, which determine the shape of the ellipse for that
cycle. The STEP in line 140 was added because the smaller
ellipses otherwise took the same time to draw as bigger ones.
Line 145 randomly selects the color register for the current line
(an interesting variation is to move this line to line 135,
making each ellipse a solid color). Line 150 plots a point at the
center of the screen. The formula in the DRAWTO in line 160
was arrived at by using simple trigonometry to determine the
point on the ellipse at any given angle around the center. The
SETCOLOR statement in line 180 changes a random color
register on the screen to a ranciom hue and intensity, and is
selected 30% of the time by line 170. Line 190 completes the
loop, and 200 allows the program to select a new ellipse shape
and keep drawing. I usually put some PRINT statements
between lines 1 10 and 120 for a message in the text winc^ow.
85
Graphics
This program allows the Atari to show off its nice range
of colors, and the plotting routine has been reduced to its bare
essentials.
186 DEG
lie GRAPHICS 7
120 DX=IHT(RHCX1>*80)
130 DY=INT(RND<1)*.40>
140 FOR L=0 TO 360 STEP (140-lJX-DY)/20
145 COLOR IHTCRHJ<1)*5>
150 FIOT 150.40
160 DRAWTO 80+DX*SIhKL>..4y+DYCOS(L>
170 IF RHD'r.l»0.3 THEN 190
180 SETCOLOF; IHT( RND:! 1 )t4 ). mi RNK 1 )*16
>.IHT<RH[Kl;':^:8>*2
190 t^tXT L
200 GOTO 120
86
Graphics
Card Games In
Graphic Modes 1 and 2
William D. Seivert
With this subroutine , yon can mix the four suit symbols with letters and
numbers in graphics modes 1 or 2, [ = heart, ] = clidi, /= diamond, and
A-V = spade.
Have you ever wanted to design a card game to play in Graphics
Mode 1 or 2, only to find that you couldn't get the suit characters
(heart, spade, diamond, and club) to appear on the screen at the
same time as the characters A, K, Q, J, and the digits through 9?
Graphics modes 1 and 2 use the character base pointer
(CHBAS, location 756) to point to the table defining the character
sets. When location 756 contains 224, you get uppercase letters and
the digits and normal punctuation. When you set it to 226, you get
small letters and the graphics characters, including the characters
for the suits. Since only 64 characters are available in these modes,
you can't have both at the same time!
Try this in Direct Mode:
GRAPHICS 2: PUT #6,ASC("]"):POKE 756,226
When the POKE takes effect, the right bracket changes to its
graphics equivalent. (So does the rest of the graphics window!) The
table to look at is in the BASIC Reference Manual, Table 9.6.
The 224 or 226 that you POKE into location 756 is the Most
Significant Byte (MSB) of the start address of the character set table.
Since these tables are in ROM, they cannot be changed directly.
Also, since only the MSB of the address is used, the table must
begin on a page boundary.
It takes a lot of work and space in BASIC to hold the table
and ensure that it is on a page boundary. However, there is an
easier way!
The following BASIC subroutine will do the job.
Now I'll explain what this does by line number.
25000,25001 Just some documentation (Remember that GOSUB
25000 will work; BASIC will skip the REMs).
25010 Location 106 contains RAMTOP, the number of pages of
RAM. Subtracting 8 leaves enough room for graphics modes 0, 1,
and 2, and allows space for the new character set table. Thus, J is
87
Graphics
the address where the table will start.
25020 Locations 144 and 145 contain MEMTOP which is
BASIC'S current top of memory. If, at the time the subroutine is
called, the program is already too big to allow for the new table, we
won't do it and leave. This implies that all arrays should be
DIMensioned and variables defined before calling the subroutine.
25030,25040 This loop moves the original table (57344 =
224*256) from ROM to the location in RAM.
25050 Each character uses 8 bytes (1 byte per TV scan line) to
define which pixels should be on for the given character. Adding
472 ( = 59*8) to the starting address gives the adclress of the left
bracket ([) character.
25060 The TRAP is used so that if the subroutine is called
more than once in a run, we won't get ERROR 9 (String DIM
Error). We need 32 bytes for string ST$ (4 characters times 8 bytes
per character). Then we cancel the TRAP sct other errors don't
come to this routine.
25070 Now we define the bytes fc:ir the four suit characters.
The keying sequence after ST$ =" is: CTRL comma, 6, ESC TAB,
ESC TAB, greater-than ESC CTRL minus, CTRL H, CTRL
comma, CTRL comma, CTRL X, less-than, ESC BACK-S, ESC
BACK'S, less'than, CTRL-X, CTRL comma, CTRL comma, ESC
CTRL minus, ESC CTRL minus, lowercase W, lowercase W, CTRL
H, ESC CTRL minus, CTRL comma, CTRL comma, CTRL X,
less-than, ESC BACK-S, ESC BACK-S, CTRL X, less-than, CTRL
comma, and the closing double quotes.
25080 Start the loop to put the bytes.
25090 Convert one character at a time to its ATASCII value and
POKE it in the appropriate location.
25100 Finish the loop.
25110 Put the address of the new table in CHBAS (location 756).
25120 Return to the caller.
That's all there is to it! Of course this method will work for any
characters you want to redefine. All you have to do is decide which
characters you can do without, and the bit patterns of the
characters you want.
With the above routine as it is, if you want a heart, use the left
bracket, etc. Use PUTs to the screen for the characters you want.
Remember that you can use inverse-video and /or add values to
change colors.
88
Graphics
For example, without using any SETCOLOR statements, try
GRAPHICS 2: GOSUB 25000
PUT #6,ASC("inverse-video of right bracket")
to get a blue Club, or
PUT #6,ASC("inverse-video of left bracket') + 32
to get a red Heart.
A Few Words of Warning
Every time you change graphics modes (even GRAPHICS n + 32
which doesn't change the screen), the Operating System resets
location 756 to 224, pointing to the normal character set. If you
want the suit characters back again, just GOSUB 251 10.
Also, if you use a graphics mode greater than 2, you might
destroy the table. So you will probably want to GOSUB 25000 after
coming out of graphics mode 3 or above.
Of course you do not have to use the same line numbers, and
you might want to remove the memory overlap check at line 25020,
but that's up to you.
Try it! You'll like it! . ,
25000 REM REDEFINE CHARACTER SET AhCi REP
LAC:E .'•• WITH LI
25001 REM DESTROYS TRAF'. USES STRIW: 3T$
fW '.iftRIABLES I Am .J
25010 J=( PEEKC 106 >-8)*25b
25020 IF .J<=PEEK(144)+256;¥;PEEK(145) THEN
? "F-ROi^^AM TOO LARGE TO REDEFINE i>iAF.S"
=GOTO 25120
25030 FOR I=y TO lti23
25040 F-OKE .J+L PEEK 57344+1;- NEXT I
2*5050 J=.J+472
25060 TRAP 25070^0111 ST$(32> TRAP 4y000
25065 Fei (FOLLOWING LINE IS PER I RID IS
C»-*JENTION —ED. )
25070 ST*="!:.}baAB TABj>;:UP}::HJ-C.. ..JiXX
{BAC:K BACKK iX} i . , } OP 1JP> ww m CUP J L , , K
X}<CBACK BACK}CX}<r.,>"
25080 FOR 1=1 TO 32
25090 POKE .J+I-1,ASC(ST$(LI))
89
Graphics
25100 NEXT I
25110 POKE 756.PEEK(10b>-8
25120 R!ETUFW
90
Graphics
Ticker Tape Messages
Eric Martell and Chris Murdock
The large text modes, [GR. 1, GR.2] are very convenient. With text
like this available, the Atari can become a useful and eye-catching
message presentation device. The following program makes use of
some simple string manipulatit:)ns, to move text across the screen in
a manner reminiscent of ticker tape or a marquee sign. Tlie actual
text movement is done by line 50 in the following manner:
The first 19 characters of the message string [A$] are printed at
position 1.5 [the vertical center of the screen]. A temporary string
[C$) is set equal to the second through the 20th characters in A$.
Then A$ is added [concatenated] to C$. Since C$ and A$ are
dimensioned to be the same length, this has the effect of attaching
the first character in A$ to the end of C$. A$ is then set equal to
C$ and printed once again.
The variable K is set up to check for any key being pressed.
This action will terminate the program in line 55. A delay loop is
inserted in line 55 to increase readability, since the string
manipulation is so fast that the letters become blurred unless slowed
down.
The rest of the program contains enough remarks to be
self-explanatory.
REM niJi.iIHG MESSAGE Pmzm] FOR T^€ ATA
RI
1 F-Rim "•iCLEARJ":RfM CLEAR: SCREEN BEFOR
E GOIW: ON
2 RtM DiiYiension str inss
10 DIM X$(10ee>.B*(l).U*<2«>.P^<2iJ>.Y$(2
0>.2*(28>
15 W$="* t t t t t t t t t " ^REM BORDER
16 Y$=Wf
19 REM Clear strir.ss and set E^^blank fo
r cleariris tWe reniriinder of Xf
2v3 y$="":B*=" "
24 R£M Input your text here
25 ? :? "Enter your ,^55^99".; ^ INPUT X$
29 REM CLEAR THE REST Cf X$ IF SHORTER T
m\ SCREEN WIDTH (19)
38 IF LEH(K*K20 THEN FOR C=l TO 20-LEN(
91
Graphics
:<$ > : X$( LEH( >^$ )+ 1 )=E$ ■ r€KT C ■ VM LEH( X$ )+ 1
35 DIM R$( LEH< X$ > ) . Cf ( LEH( X^ ) ) ■ A$=MI
39 FBI GOTO ORAPHICS fttDE 2+16 AHD PRD]!
STRiw:s
40 GRAF'HICS 18
45 REh tlwe borders of stars
AS POSITION L3:? #6;Yf(1.19>:p*=W$(2> = P
: m=?$
■1 #6;y$(1.19):2$=Y*(2):2
■■\'$=2t
49 REM tlix'e rnessase strins and check loc
at ion 764 to see if a kea ojas struck
50 F-OS I T I Oi 1 .. 5 •■ ? #6 ; H*( L 1 9 > ■ C*=R*( 2 ) : C
*< LEN< C$ >+ 1 )=A$ : AI=C$ : K=PEEk:( 764 )
54 REM F'ause to increase readability, se
t color randiDtftla^ and reset attract tlas
idEH'rpiJ'+lMOf
47 POSITIOH 1..7
*(LEH'::Z$>+1)=Y$
55 FOR TI=1 TO 5Q-mil TLF-CiKE 77.0-3ETC:
OLOR IHT(RND<:0>*4>.INT(F^<0>*15).8aF K
=255 THEN 46
Graphics
Player/Missile Graphics
With the Atari Personal
Computer Systems
Chris Crawford
Some think that this is among the very best ideas printed about the Atari
to date. Study it, experiment, and the techniques here will considerably
amplify your programming skills.
Anybody who has seen ATARI'S Star Raiders^*^' knows that the
Atari Personal Computer System has vastly greater graphics
capabilities than any other personal computer. Owners of these
computers might wonder if they can get their machines to do the
fabulous things that Star Raiders does. The good news is that you
can indeed write programs with graphics and animation every bit as
good as Star Raiders. In fact, I think it's possible to do better. The
bad news is that all this video wizardry isn't as easy to use as
BASIC. The Atari computer is a very complex machine; mastering
it takes a lot of work. In this article I will explain just one element of
the graphics capabilities of the Atari Personal Computer System:
player-missile graphics.
Player-missile graphics were designed to meet a common need
in personal computing, the need for animation. To understand
player-missile graphics you need to understand the old ways of
doing animation on machines like the Apple. These machines use
what we call pure playfield graphics, in which bits in RAM are
directly mapped onto the television screen. You move an image
across the screen by moving a pattern of bits through RAM. The
procedure you must use is as follows: calculate the current addresses
of the bit pattern, erase the bit pattern from these addresses,
calculate the new addresses of the bit pattern, and write the bit
pattern into the new addresses.
This can be a terribly slow and cumbersome process,
particularly when you arc moving lots of bits (large objects or many
objects) or when the motion is complex. Consequently, most
animation on computers like the Apple is limited to pure horizontal
motion, pure vertical motion, small objects, or slow motion.
Animation like you get in Star Raiders is utterly impossible.
93
Graphics
To understand the solution to this problem you must
understand its fundamental cause. The screen image is a two-
dimensional entity, but the RAM that holds the screen image is a
one-dimensional entity. Images that are contiguous on the screen do
not necessarily occupy contiguous RAM locations (see Figure 1). To
move an image you must perform messy calculations to figure out
where it will end up in RAM. Those calculations eat up lots of time.
We need to eliminate these calculations by shortcutting past the
2d-to-ld transformation logjam. What we need is an image that is
effectively one-dimensional on the screen and one-dimensional in
RAM.
Let's set aside a table in RAM for this one-dimensional image.
We'll call this table and its associated image a player. We'll have the
hardware map this image directly onto the screen, on top of the
regular playfield graphics. The first byte in the table will go onto the
top line of the screen. The second byte will go onto the second line
of the screen, and so on down to the bottom of the screen.
Although I'm calling the image one-dimensional, it's actually 8 bits
wide, because there are 8 bits in a byte. It's a straight bit-map; if a
bit in the byte is turned on, then the corresponding pixel on the
screen will be lit up. If the bit in the byte is turned oH, then the
corresponding pixel has nothing in it.
We can draw a picture with this scheme by turning the
appropriate bits on or off. The picture we can draw is somewhat
limited; it is tall and skinny, only 8 bits wide but stretching from the
top of the screen to the bottom. Let's say we want to draw a picture
of a little spaceship. We do this by storing zeros into most of the
player RAM. We put the bits that form the spaceship into the
middle of the player RAM so that it appears in the middle of the
screen. See Figure 2 for a depiction of this process.
So far we don'fhave much: just a dinky image of a little
spaceship. How do we get animation? We move it vertically with the
same technique that other computers use. First we must erase the
old image from RAM, then we draw in the new image. This time,
however, the problem is much simpler. We move the image down by
moving its bit pattern one byte forward in RAM. We move the
image up by moving its bit pattern one byte backwards in RAM.
We use no crazy two-dimensional calculations, just a simple one-
dimensional move routine. It's trivial in BASIC and easy in
assembly language. Horizontal motion is even easier. We have a
hardware register for the player called the horizontal position
register. When we put a number into the horizontal position
94
Graphics
register, the player is immediately moved to that horizontal position
on the screen. Put a big number in and POW! — the player is on
the right side of the screen. Put a little number in and POW! — the
player is on the left side of the screen. Horizontal motion is achieved
by changing the number you put into the horizontal position
register. The two techniques for horizontal and vertical motion can
be mixed in any way to produce any complex motion you desire.
This is the two-dimensional screen image
Here are the corresponding bytes in RAM (hexadecimal)
99
Bd
FF
Bd
99
This is how the bytes would be plac
ed in one-dimensional RAM. Note how
the bytes that make up the spaceship are scattered through the RAM. What
a headache!
99
Bd
FF
95
Graphics
Bd
Bd
99
Figure 2
How to draw in binary
graphical
representation
one byte binary hexadecimal decimal
8 bits representation representation representation
m
.^10011001 99 153
-10 11110 1 Bd 189
— 11111111 FF 255
— 10 11110 1 Bd 189
"^10011001 99 153
The capabilities I have described so far are nice, but taken
alone they don't give you much. That's why Atari added a long list
of embellishments to this basic system which enormously extend its
power. The first embellishment is that you have not just one, not
two, not three, but FOUR (count 'em, FOUR) players available.
This means that you can have four little spaceships flying around on
the screen. They are all independent and so can move
independently. The next embellishment is that each player has its
own color register. Thus, you can set each player to a different
color, completely independent of the ct:)lors in the playfield. This
gives you the capability of putting up to nine colors onto the screen,
depending on your graphics mode. Next, you have the capability of
making a player double or quadruple width. This doesn't change
the eight-bit resolution of the player, but it does allow you to make
him fatter or skinnier as you please. Next, you can select the vertical
96
■^
Graphics
resolution of the player to either single line resolution (each byte
occupies one scan line on the screen) or double line resolution (each
byte occupies two scan lines on the screen. Next, you can select the
image priorities of players versus playfield. Since both players and
playfield will be imaged onto the same location of the screen you
have to decide who has priority in the event of a conflict. You can
set players to have higher priority than playfield, playfield to have
higher priority than players, or several mixtures of player-playfield
priority. This allows you to have players disappear behind playfield
or vice-versa. Finally, you have tiny two-hit players called missiles.
Each player has one missile associated with him. The missile takes
the same color as the player but can move independently of the
player. This allows bullets or other small graphics items. If you
want, you can group the four missiles together to form a fifth player.
They then get a separate color.
How do you use all of these fantastic capabilities? You think
that it would be terribly difficult to put all of this together into a
program, but it isn't. Listing 1 shows a program that puts a player
onto the screen and moves it around with the joystick. As you can
see, the program is ridiculously short. Here's how it works:
Line 10 sets the background color to black (the better to see the
player by). It also sets up our starting positions, X being the
horizontal position and Y being the vertical position.
Program 1. Program to demonstrate player-missile graphics.
le SETCOLOR 2.0.0-X=120-Y=48=REM set bac
ksround color and player position
20 A=PEEK(106;-8=PiJKE 54279,A = PnBASE=25b
*A = REI1 Set plaaer-missile address
30 POKE 559.46:P0KE 53277, 3^REri Erable P
f1 sraploics witl'i 2-1 ine resolution
40 POKE 53248. X: REM :5et l-crizontal posit
ion
50 FOR I=Pt1BASE+512 TO PMBASE+640 = piJKE I
,0=MEXT TREM Clear out player first
60 POKE 704. 216 : REM Set color to sre&■^
70 FOR I=FtlBA3E+512+Y TO Pt1BASE+51b+Y.F£
AD ft = POKE LA-f€XT TREM Draw player
80 DATA 153. 189,255. 189. IK
97
Graphics
90 REM Now coTies tl^e mot ion rout ire
106 ft=STICK(8):IF A=15 im\ OJTO im
lie IF A=ll THEN X=X-^POKE 53248. M
120 IF A=7 THEN X=X+l:pJKE 53243 ..X
\1& IF A=13 THEH FOR 1=6 TO S STEP -l^F'O
KE R'BASE+5 12+Y+I . PEEK':: P^ASE+S 1 1 +Y+ 1 ) ^ N
EXT I:Y=Y+1
140 IF A=14 THEN FOR I=vj TO fc^POKE PMBAS
E+51 1+Y+LPEEK( FtlBASE+S 12+Y+I ) ■■ h£XT I ^ Y=
Y-1
150 GOTO 100
Line 20 finds the top of RAM and steps back eight pages to reserve
space for the player-missile RAM. It then pokes the resultant page
number into a special hardware register. This tells the computer
where it will find the player-missile data. The players are arranged
in memory as shown in Figure 3. Finally, line 20 keeps track of
where the player memory is through the variable PMBASE. Because
of this arrangement, this program will work on any Atari Personal
Computer System, regardless of the amount of RAM in place. The
number of pages by which you must step back (8 in this case)
depends on how much memory your graphics mode consumes and
whether you are in single-line resolution or double-line resolution.
In any event, the number of pages you step back must be a multiple
of 4 for double-line resolution and a multiple of eight for single-line
resolution.
Line 30 first informs the computer that this program will use
double-line resolution. Poking a 62 into location 559 would give
single-line resolution. The next instruction enables player-missile
graphics; that is, it authorizes the computer to begin displaying
player-missile graphics. Poking a into location 53277 revokes
authorization and turns off the player-missile graphics.
Line 40 sets the horizontal position of the player.
Line 50 is a loop that pokes O's into the player RAM area. This
clears the player and eliminates any loose garbage that was in the
player RAM area when the program started.
Line 60 sets the player's color to green. You can use any color you
want here. The colors here correspond exactly to the colors you get
from the SETCOLOR command. Take the hue value from the
SETCOLOR command, multiply by 16, and add the luminosity
value. The result is the value you poke into the color register.
Graphics
Line 70 reads data bytes out of line 80 and pokes them into the
player RAM area. The bytes in line 80 define the shape of the
player. 1 calculated them with the process shown in Figure 2. Here
you have lots of room for creativity. You can make any shape that
you desire, as long as it fits into eight bits. You want more bits? Use
four players shoulder to shoulder and you have 32 bits. You can
make the look longer to give more vertical height to your player.
These seven lines are sufficient to put a player onto the screen. If
you only put in this much of the program, and ran it, it would show
the player on the screen. The next lines are for moving the player
with the joystick plugged into port 0.
Line 100 reads the joystick.
Line 110 checks to see if the joystick has been moved to the left. If
so, it decrements the horizontal position counter and pokes the
horizontal position into the horizontal position register. The line
does not protect against bad values of the horizontal position
(X<1orX>255).
Line 120 checks to see if the joystick is pressed to the right. If so, it
increments the horizontal position counter and pokes the horizontal
position into the horizontal position register.
Line 130 checks to see if the joystick is pressed down. If so, it moves
the player image in RAM forward by one byte. There are six bytes
in the player image that must be moved. When it has moved them,
it increments the vertical position counter.
Line 140 performs the same function fcir upward motion.
Line 150 starts the joystick poll loop over again.
This program was written to help you understand the principles of
player-missile graphics; as such it has many weaknesses. It also has
much potential for improvement. You might want to soup it up in a
variety of ways. For example, you could speed it up with tighter
code or an assembly language subroutine. You might add more
players; perhaps each could be controlled by a separate joystick. You
could change the graphics shapes. You could make the colors
change with time or position or how much fuel they have left, or
whatever. You could add missiles for them to shoot with. You could
change width to give the impression of 3D motion that Star Raiders
gives. You could add playfield priorities so they could move behind
some objects, but in front of others. The possibilities are almost
limitless.
99
Graphics
Figure 3
Player-missile graphics RAM positioning
PMBASE must be on IK boundary for double-line
resolution,
2K boundary for single-line resolution
PMBASE
+ 128
+ 256
+ 384
Missiles
+ 512
+ 640
+ 768
+ 896
+ 1024
double-line
resolution
single-line
resolution
unused
unused
M3
M2
Ml
MO
Player
Player 1
Player 2
M3
M2
Ml
MO
Player 3
Player
Player 1
Player 2
Player 3
PMBASE
+ 768
Missiles
+ 1024
+ 1280
+ 1536
+ 1792
+ 2048
100
Graphics
Useful addresses
(all values in decimal)
559 put a 62 here for a single line, a 46 for double line
resolution
623 sets player/playfield priorities (only one bit on!)
1: all players have priority over all playfield registers
4: all playfield registers have priority over all players
2: mixed. PO & PI, then all playfield, then P2 &. P3
8: mixed. PFO & PFl, then all players, then PF2 & PF3
704 color of player-missile
705 color of player-missile 1
706 color of player-missile 2
707 color of player-missile 3
53248 horizontal position of player
53249 horizontal position of player 1
53250 horizontal position of player 2
53251 horizontal position of player 3
53252 horizontal position of missile
53253 horizontal position of missile 1
53254 horizontal position of missile 2
53255 horizontal position of missile 3
53256 size of player (O = normai, l=double,
3 = quadruple)
53257 size of player 1 (O = normal, l=double,
3 = quadruple)
53258 size of player 2 (O = normal, 1 =double,
3=quadruple)
53259 size of player 3 (O = normal, 1 =doublc,
3 = quadruple)
53277 A 3 here enables player-missile graphics, a
disables them.
54279 put high byte of PMBASE here
101
Graphics
The Basics of Using POKE
in Atari Graphics
Charles G. Former
Did you ever wonder how the Atari can store 61,440 [jixel in less than
8,000 bytes? With the information in this article, you'll have the
background to create graphics in machine language, high-speed screen
save/recall, mix text and graphics, and lots else.
In order to use the poke statement in Atari graphics, we must first
know two things:
1) Where to poke
2) What to poke
To display where to poke, we must look at the display list for each
graphics mode. This display list is found by PEEK (560) + PEEK
(561) *256. The display list determines how the memory is displayed
on the screen. The 5th and 6th byte of the display list hold the
addresses of the first byte to be displayed. Table l-I gives the
starting address for each graphics mode plus other information.
Determining what to poke involved trial and error with the
following results:
1) Graphics Modes 3, 5, 7, 19, 21, 23
These modes are four color modes which display only four pixels for
each eight bit byte of memory displayed. Bits 7 and 6, numbered as
7-6-5-4-3-2-1-0, determine the color of the first (left -most) pixel; bits
5 and 4 the second; 3 and 2 the third; and 1 and the fourth. The
two control bits act as a "COLOR" statement for each pixel. If the
hex value of the two control bits equals it corresponds to a
"COLOR 0" statement; if they equal 1, they correspond to a
"COLOR 1" statement, etc.
2) Graphics Modes 4, 6, 20, 22
These modes are two color modes which display eight pixels for
each eight bit byte of memory. Each bit acts as a "COLOR"
statement for an individual pixel. A one in a location corresponds
to a "COLOR 1" statement and a zero corresponds to a "COLOR
0" statement.
3) Graphics Mode 8, ^l='a'y
These modes are high resolution modes with only one color. They
display eight pixels per memory byte with a "1" bit displaying a
102
Graphics
TABLE 1-1
BITS
#OF
GRAPHICS
DISPLAY
#OF
#OF
BYTES
DISPLAYED
COLORS
MODE
DATA ADDR.
ROWS
COLUMNS
PER ROW
PER BYTE
AVAILABLE
3
2-int
20
40
10
4
4
2W16
40
80
10
8
5
2H56
40
80
20
4
6
224%
80
160
20
8
7
20576
80
160
40
4
e
NtlTE 1
160
i20
40
8
19
24176
24
40
10
4
20
2Wi(i
48
80
10
8
21
2HS6
48
80
20
4
22
224%
06
160
20
8
23
20S76
96
160
40
4
21
16720
112
160
40
8
NOTE#l:
Cirn,
4H;-Mi.Lli-Hhn^
ruo iiuklrfssL"' - 16720 is
llu' sTiirliliii ikl
kh-rss
for the first
HOli
111-- iinJ 20480 is
tiiL' sliirlii
iH^ilUfc-^ fi.r ih
fsaonj 80 lir
K-s.
pixel of the same color as the background but with a higher
luminane. A "0" bit displays a pixel of the same color and
luminance as the background.
The "COLOR" statements mentioned in the above explanations
indirectly control the color of each pixel by determining which
color register is active for an individual pixel. The exact manner in
which a "COLOR" statement chooses this register is explained in
Table 9.5 of the Atari-Basic Reference ManuaL
Here's an interesting program to get started in graphics:
18 GRAF-HICS 5
26 A00f'=F'EEK<56e>+PEEK(561 )t25e
38 rOOR=PEEK'; hDDR+4 )+PEEK( rDDR+5 )*25b
48 B=IHT(F:i'D:0)ty8e>^REM -
PICK A FlAhCiOM B'i'TE IN DISPLAY
58 R=IHT(R^Ci';:ti)«255>^R£ri -
PICK RHtCiGM UALIJE BET14EEM 8 ftf^D 255
68 FiiK.E hDOR+B. H FEM -
POKE R'WCti'JM i..i(HLUE INTO m\Lm BYTE
78 GO TO 40
References: "Atari 400/800 Basic Reference Manual," Copyright
1980, Atari, Inc.
103
Graphics
A note on using the basics of POKE . . .
Larry rewrote the original program that Charles sent in so it will
adjust itself to your machine's memory. After you try the program
in the article, take a look at these. I expanded them to randomly
alter the SETCOLOR parameters . . . you'll discover some of the
versatility of your machine after you let the program run for five
minutes or so.
10 GRAPHICS 23
20 AOClF:=PEEK( 568 >+?£&:•; 5bl>t25fc
30 rdof^f-eek--; ADDR+4 >+PEEK( AKiR+S ):^-.25t;
35 I=IHT<RHD';0>*16>
36 j=\m<9m:.vyms)
37 K=IHT(RHD(0)*5)
38 StTCCiLOR K...J..I
40 E:=INT(RHJ-:;i3)*384y)F£M -
PICK A RAHDOM BYTE IN DI:5F1AV
50 A=IHT(Rm( 0)^255;- REM -
PICK RAtDiJM I...IALUE BETWEEN y RHD 255
60 F'lJKE ADDR+B.AREn -
POKE RlAhflJOn ItALUE INTO m€\m B'lTE
70 buTO 35
10 GRAPHICS 7
20 RDOR=PEEK(560;'+PEEK(561;'*25b
30 A[)OF:=PEEK( ADDR+4 )+FtEK( Ri30F:+5 y^25&
35 I=IHT(RhCK0>:nb>
36 .>INT<W»;0)*16;'
37 K=INT-:F^K0)*5)
38 SETCCtOF: K;.J. I
40 B=IHT(RHD'::0)*32y0)^REM -
PICK A RA^OjM BYTE IH DISPLAY
50 rt=IHT(RND<0)*255;-REM -
PICK FHfOJM UALLE BETl-JEEl-^ S AND 255
60 PO^.E hDOF:+B,A:REM -
pok:e m-Dm iialue into rancjijm b'/te
70 GOTO 35
104
Graphics
Designins Your Own
Atari Graphics Modes
Craig Patchett
This one is on the list of "things you 'gotta know" about the Atari. Get
set for some video magic.
The graphics modes that Atari supplies with their 400 and 800
computers are nice, but what if you want a little more? For example,
how about a large-type heading, with a smaller-type sub-heading
below it, all over a graphics display? Terrific, you say, but you're not
an Atari engineer? Don't worry about a thing. With this article, a
little concentration, and some time in front of the keyboard, you'll
have Atari graphics modes performing at the snap of your fingers.
First, a simple explanation of what we'll be doing. In a series of
memory locations deep inside your Atari rests a special list of
numbers that tell the computer which graphics mode it's in. Each
time you change graphics modes, this list also changes. But wait a
minute. Why a list of numbers instead of just one? Because there is
one number for each graphics row on the screen. For example, in
graphics mode 2+16 (no text window) there are twelve graphics
rows, so there would be twelve numbers in the list. For graphics
mode 7+16, there would be 96 rows, or 96 numbers. The table
labeled Modes and Screen Formats in your Atari BASIC reference
manual shows the number of rows in each graphics mode. We'll be
referring to it again later.
As I said before, when you change graphics modes, using the
GRAPHICS command, the list changes. It may become longer or
shorter, depending on the mode, and the numbers in it will change.
But the numbers will all be the same. Obviously, since they stand
for the graphics mode of each row on the screen, if half of them
were one number and the other half another, then half of the screen
would be one mode and the other half another. This is not how
Atari BASIC was designed. It is, however, what we want. So what
we're going to be doing is changing the numbers in the list to make
the screen behave the way we want it to. Let's take a look at exactly
how it's done.
How Much Of Each Mode Should I Have?
The first thing we have to do is figure out exactly how we want the
105
Graphics
screen to look. Let's take the example from the beginning of the
article — a large-type heading (mode 2), with a smaller-type sub-
heading below it (mode 1), all over a graphics display (mode 3).
Unfortunately, we can't just decide to have, for instance, four rows
of mode 2, two rows of mode 1, and nine rows of mode 3. There's a
simple rule we have to follow in deciding how many rows of each
mode we're going to have.
You may already know that your television picture is made up
of hundreds of little lines going across the screen from top to bottom
(if you don't, you know now!) If you look closely at the screen, you
can probably see them. These lines are formed by a single beam of
light that scans the screen very quickly (sixty times a second) to
make the picture, so we'll call them scan lines. The part of the
screen that your Atari lets you use for graphics has 192 of these
lines.
Each graphics row is a certain number of scan lines "high." In
mode 1, for example, each row is eight scan lines high. If you look at
the Table of Modes and Screen Formats that I have mentioned
before, you'll see that there are 24 rows in mode 1 (remember, we're
only interested in "full screen.") Surprise! Twenty-four rows, each
eight scan lines high, means 8x24= 192 scan lines in all. To figure
out how many scan lines high the rows in other modes are, just look
at the table and divide 192 by the number of rows in a full screen.
The reason we need to know all this is because we must make
our new mode so that it has a total of 192 scan lines. No more, no
less. This means you have to do a little bit of juggling around with
the different modes you want to use, but it's really not all that
difficult. I'll demonstrate with our example. Let's suppose we need
three rows of mode 2 and two rows of mode 1. All we need to do is
figure out how many rows of mode 3 we should have to make a total
of 192 scan lines. We look at the table and figure out that in mode
2, each row is sixteen (192 scan lines/12 rows) scan lines high. Since
we want three rows of mode 2, that makes forty-eight scan lines so
far. Similarly, we want two rows of mode 1, which uses eight (192
scan lines/24 rows) scan lines for each row. So that makes another
sixteen scan lines, or sixty-four all together, which leaves us 192 -
64= 128 scan lines still left over. We'll use these for mode 3. We look
at the table again and see that mode 3 uses eight scan lines for each
row also, so how many rows do we need? 128 leftover scan lines/8
scan lines per row of mode 3 = 16 rows of mode 3.
So now we know that our graphics mode is going to have three
rows of mode 2, two rows of mode 1, and sixteen rows of mode 3.
106
Graphics
Let's tell the computer.
How Do I Tell The Computer?
We have to start by telUng the Atari in a graphics mode it
understands. Of course, we can't use just any mode, but this time
the rule is a lot easier. Out of the modes you're going to be using,
take the one that uses the most memory (look at the table under
"RAM required"). In our example, mode 1 uses the most memory,
so the first line in our program is:
10 GRAPHICS 1
The next step is to find out where the list of numbers begins. Since
it isn't always in exactly the same place, we must PEEK into the
computer's memory at two locations that tell us where it is. Since
we'll need to use the number that tells us where the list begins later,
we'll give it a name:
20BEGIN = PEEK(560) + PEEK(561)*256 + 4
This line will always be the same no matter what modes you are
going to be mixing.
The third step can be ignored if the mode you want at the top
of the screen is the same as the one that uses the most memory. If
not, as in our example (mode 2 is at the top of the screen, mode 1
uses the most memory), then we have to change the number in the
memory location right before the beginning of the list. The table
below shows what number to use for the mode at the top of the
screen.
MODE 012345678
NUMBER 66 70 71 72 73 74 75 77 79
So, for example, we would need:
25 POKE BEGIN- 1,71
Remember, only do this step if the first graphics row is not the same
mode as the one that uses the most memory.
Now we just have to go down the list and change the numbers
that need to be changed. The numbers for the graphics mode with
the most memory are already correct, since we start in that mode.
Therefore, all we have to change are the other numbers. In our
example, that would be the numbers for mode 2 and mode 3. To
make the necessary changes, we simply POKE BEGIN + row
number with the correct number for the mode we want in that row.
What are the correct numbers? Just subtract sixty-four from the
numbers in the table I gave above. That would mean, for example,
107
Graphics
seven for mode 2, and eight for mode 3. So we have:
30 POKE BEGIN +2,7:POKE BEGIN +3,7
which takes care of mode 2. Note that we didn't POKE BEGIN + 1.
This was automatically taken care of when we POKEd BEGIN- 1 in
line 25. Remember that we also don't have to worry about the
numbers for mode 1, since they are already correct. Therefore, all
that's left is to change the numbers for mode 3. Since we want
sixteen rows of mode 3, which means changing sixteen numbers,
we'll use a FOR/NEXT loop to make life easier:
40 FOR ROW =6 TO 21:POKE BEGIN + ROW,
8:NEXT ROW
Now the list has the correct mode numbers in it. There's still
one more thing we must do. Since there may be a fewer number of
rows now than there were in the mode we told the computer to
start with, we have to tell the computer where the new end of the
list is. We do this by POKEing the number 65 into the row number
right after the last one we used. This tells the Atari to go back to
the beginning of the list. We also tell it where the beginning is. For
our example;
50 POKE BEGIN + 22,65:POKE BEGIN + 23,
PEEK(560):POKE BEGIN +24, PEEK(561)
And now we're done. Note that the only changes that you would
need to make in line 50 when designing your own modes is in the
numbers 22, 23, and 24. These are just the three row numbers after
the last one you use on the screen.
How Often Do I Have To Do All This?
This whole procedure must be repeateci whenever you want to use a
specially designed graphics mode. Yc:)u can't skip any of the steps
except for the third one, and then only under the condition I
already described.
So Now What Do I Do?
The last thing I'm going to cover is how to print and draw in your
new mode. This only applies if the row you want to print or plot on
is within the normal range for whatever mode it is. In simpler terms,
if we had put the sixteen rows of mode 3 at the top of the screen,
and mode 2 at the bottom, then mode 2 would have been in rows,
19, 20, and 21. But mode 2 usually only has twelve rows, so if you
tried to print on line 19 you would get an error message. Now, there
is a way around this, but it's somewhat complicated so I'm going to
leave it for a future article. For now, however, you can use the
108
Graphics
following rules as long as you stay within the normal range of the
mode you're working with.
The first thing you have to do is POKE location eighty-seven
with the number of the graphics mode for the row you want to
PRINT or PLOT in. Next, POSITION the cursor and PRINT, or
PLOT and DRAWTO. When you tell the Atari to POSITION X, Y
or PLOT X, Y, the X value is still the number of spaces in from the
left that you want to go. The Y value is still the number of rows
down from the top that you want to go, but you may have to
experiment with different values to get it exactly where you want it.
Just make sure that you remember to POKE 87 with the mode
number you're going to PRINT or PLOT in.
To help you understand what I just said, and to show off the
example mode we've been working on, try entering these lines, as
well as the other ones that are included throughout the article.
When you've entered them in, just RUN the program, and BREAK
in when you're done. Notice that the commands for colors are the
same in the new mode; that is, you can still print different color
letters and use the COLOR command for graphics points, etc.
The one difficulty that might rise is when you mix mode with
other modes. Since mode has a different background color (blue)
than the other modes (black) you will have to use the SETCOLOR
command to make the mode rows invisible. Otherwise, you
should have no problems whatsoever.
60 SETCOLOR 4..4..2:REri Ewi:K;GROiJHD
70 POKE S7..2^P05ITI0N b.O^PRINT <lb;"THIS
IS":pOSITION 3. SPRINT lib; "GRAPHICS MOO
E"=P&5ITIa■^ 3..2:FP:IHT #fc'.; ''TWO"
80 POKE S7.1:POSITI0H b.l^PRIMT #b,;"t.hx5
i5"=P0SITI0H 1,4^PRINT #6; '■-rdPhics ,Y,od
e c*te"
98 POKE 37. 3^ COLOR 3^ FOR LIHE=i TO 3^ PLC
T 15.LIHE*5+8:DRrtHT0 22.LIrO:5+8:r€XT LI
hE^PLOT 22.13^DRftHT0 22; 23
100 GOTO 100: REM KEEP GRAPHICS OH SCREEM
Look, Ma, New Modes!
That's all there is to making your own graphics modes on your
Atari computer. The easiest way to make sense of everything I've
covered here is to experiment. Start off by changing the example
109
Graphics
program and watching what happens, and then try designing your
own modes. Just a little practice and in no time you'll be an expert.
Above all, have fun doing it; after all, the Atari works for you, not
the other way around.
110
Graphics
Graphics of
Polar Functions
Henrique Veludo
One interesting type of program allows you to explore relationships
between numbers and their visual analog. The routine here plots polar
functions — this might not drive you wild until you realize that this means
spirals and roses. A more seductii'e introduction to the beauty of math is
difficult to imagine.
This program will plot polar functions such as roses, spirals,
polygons, on the high screen of the ATARI 800, with
input from the programmer. The general equations for converting
the polar coordinates to rectangular coordinates are as follows:
cosO =
sinO =
X,Y
X = rcosO
y = rsinO
First, the program will display a function menu (line 100), then ask
the user to input which function to display, together with its
parameters, INCR(element) and SC(ale). The INCR(element) is the
interval in degrees that the computer uses to "increment" the angle
T from 0° to 360°. One must decide whether the speed of execution
or accuracy in plotting is preferable. A small INCR(element), e.g.
0.1, will draw a very accurate graph very slowly. A larger
INCR(element), e.g. 5.0, will draw much faster and less accurately.
An INCR of 1.0 is a good compromise. The SC(ale) is included to
allow the graph to fill most of the screen. Without it, some functions
will appear too small, others will be too large to plot. A SC(ale)
between 10 and 100 should do for most functions. Lines 220 to 226
check for a input that might confuse the program and display an
111
Graphics
error message. Line 230 asks if the x-y axes are to be displayed and
lines 390-395 display them. Lines 300-370 will select random colors
and intensities (with enough separation to be visible). Lines 400-690
contain the calculation and plotting routines for x,y. In line 410 the
variable U is included for use with the spiral function and dictates
how many revolutions the spiral will have; it can be changed at line
222. Line 420 converts degrees to radians (in this context the
program seems to work better with radians, but it could be
converted to degrees, with the DEG function, and changing the
values of the functions). Line 430 will direct the program to the
proper function chosen in the input. Lines 610-620 calculate the x,y
coordinates. Line 630 will check for an out-of-range cursor, stop the
drawing, and avoid an error message. Line 670 will activate the
buzzer to signal that the plotting is over. Lines 680-690 wait for a
key to be pressed to clear the screen and return to the menu. If the
buzzer sounds without anything being plotted, it means that the
function is too large to plot. (Decrease the SC(ale) value to
continue.) I chose to use randomly-selected colors. They could be
chosen by the user in an input statement as well (where you input
the parameters after the menu display).
Here are some values for the functions that work beautifully:
R = Q:SC=4:INCR = 60
R = 2(I-SIN(Q):SC = 20
R = COS(2 SIN(6 (Q))):SC = 90
R = S1N(COS(100 Q)):SC = 90
R = COS(2 SIN(2 Q)):SC = 90
R = I:INCR = 45:SC = 60 polygon
R = 2(I+COS(Q)):SC = 20
R = SIN(3(Q)):SC = 80
R = SIN(4COS(2Q)):SC =90
R = COS(3SIN(Q)):SC = 90
R = COS(SIN(100 Q)):SC = 90
R = I:INCR = I20:SC = 80 triangle
10 F£M PROi^FhM TO PLOT POLhR FUHCTIOHs
20 REM BY HB*.:IQUE UELUDO FCft ATAF:I Sfje
80 DIM frl(l)
98 ? "}"
100 POSIT ICW 7..1^? "GF^PHS iJF FiJlRF: FLIC
TlOt-ri"
110 POSITICW 2.3^? "FUHCTIOH MENLL"-?
112
Graphics
128 "■ " l;'ft=B*Q SPIRAL
II
1 38 '^- " 2 :>R=A*': 1 +ClG( Q > ) CAFD 1
ID"
140 ■"• " 3)R=A:^(1-SUKQ>)"
158 ■■• " 4>R=A:^cSIH'::E»Q) ROSE"
IbS "■ " 5;'R=ft>cL;0S(B*Q)"
170 ■'■ " b>R=CuS(H-i!SIN(E:*Q;'>"
188 ■"• " 7>R=SIN':;ft^CDS(B*G!;j>"
198 ? " S::'R=A POLYGO
H"
208 •■• :V :? "IKF1IT:":V
210 ■•■■ "FUHCT lOH *; A.. B.. INCR . .. ;5C .%■ It^'UT
H,.A..B.. IHCR..SC
220 IF H=0 TI€H H=l
222 IF H=l im\ U=4
2ZA IF R=0 im\ A=l
■22b IF B=0 THEN B=l
238 V :•? :? "DO YOll l-JAHT THE X-Y A;=(ES DI
SFLAYED";
240 I^PUT AJ^F A$(1..1)="Y" THEN l'i=l
3m OX.0R MjR'AF'HICS 24
310 I=IHT<RHD(l>^lb>
320 Ll=im(RhC(l)*8>*2
330 L2=IHT(RhCi(l>*8>*2
348 IF ABS(L1-L2)<4 THEM 328
358 SETCCtOR 4.LL1
368 SnCOLOR 2..LL1
370 aTCOLOR 1..LL2
388 IF WOl im\ 418:RB1 — OISFtAY AXES?
398 FOR: I=w TO 319 STEP 4-FluT Lyg^he^T
I
395 FOR 1=8 TO 191 STEP SFtuT 168.. I ^ HEX
T I
400 F.£fi FIOTTIHG i j^Lf:IJLAT I W
418 FiJF: T=0 TO 366>VU STEP" HCR
42'0 C!=T.-57 . 3
430 Lii H iJjTO 5 10. .520 .538 .540. 558 ..568 ..57
0..5Ffi
500 F.fi-1 EOIJATIONS FiOR R
518 F:=B*Q^yJTO 618
113
Graphics
520 R^=ftt.( l+Cffix; Q ) > ^ GOTO 610
530 F.'=A;^'(1-SIN<Q)>:G0TU bl0
540 F:=A*SI^•^■:;B*Q::-GOTO 619
550 F.:=A*CO£:':: B^W! ): UJTO 610
560 F-^iOS': A5K3 1 H( E*Q ) ) ■ i JJTO 610
570 F:=SIH<ft*i::OS(B:^Q))-QLiTO 610
580 F:=A-QJTO 610
600 F.£f1 PLOTTW: X.Y
6 1 y.= I HK < R*CiJS( Q ) )*SC )
620 Y=lHT<(RtSIhKQ>)*SC)
630 IF AB3(X»159 OR ABS(V»95 imi 670
640 IF T=0 THEN FIOT 160+X.96-Y
650 C*<hWTO 160+X..96-Y
660 tCXT T
670 FW: 1=1 TO 75^ POKE 53279 .. : ^€XT I
675 i-^i
680 i>MJFtH ttL4,0.."K^"^GET #LX: CLOSE
#1
690 m #6. iz^m:oto 9a
114
CHAPTER FOUR:
Prosramming Hints
115
Programming Hints
Reading the Atari
Keyboard on the Fly
James L. Bruun
For most programs, the normal method of using the INPUT
statement to get keyboard characters into a program is perfectly
satisfactory. There are times, however, when we need to get a
keystroke without stopping the program to wait for a key to be
struck.
The ATARI computer has all the features needed to enable the
programmer to check the keyboard without waiting for an INPUT
statement to get the character. Memory location 764 retains a key
code for the last key pressed. Further, when the RUN command is
executed, that cell is set to 255 to indicate that no key has been
pressed. During the running of a program, that location can be
POKEd with a 255 to indicate that we've checked it since the last
key was pressed.
Cell 764 is POKEd with 255-'only if it isn't already finding it
255, then having a key pressed while the POKE 764, 255 instruction
is being interpreted. This would cause the keystroke to be lost. In a
long program the keystroke isn't often lost, but in a short program
it happens quite often.
The following program illustrates the use of these features in a
subroutine. First, initialize an I/O buffer and string variable.
10 OPEH #L4.0/'K:"
20 Din CHAR$(1>
Then build the subroutine. Always precede your block of
subroutines with an END statement to prevent accidental
execution.
30 PRINT "CCLEAF:}"
40 POKE 752. 1
50 GOSUB 5080
60 IF CHAR-0 THEN 58
70 POSITION 5,5
80 PRINT "CHhRhCTER=< M:;HAR$; " )"
90 GOTO 50
4999 EHD
5000 C:HAR=0
116
Programming Hints
5010 IF F'EEK'::764K>255 im\ fJEl #LC.HAR.^
CHAR$=CHR$0::HAR)
5020 RETURN
Most programs that would need this feature would perhaps be doing
complex things if the keystroke has not occurred, but in this one we
have chosen to "do nothing" until a key is pressed.
117
Programmins Hints
Atari Sounds Tutorial
Jerry White
This program was designed to help you discover some of the
amazing sounds of Atari. You will enjoy experimenting with this
program and learn at the same time. Here's how it works:
We will use two FOR-NEXT loops to alter the volurne and
pitch variables of the SOUND command. You will be prompted to
type the required data. The program will then execute using your
data and you will hear the sound you created. Here is sample data
for you to use to get the feel of the program. Respond to the
prompts with Dist 10, Pitch 20, LI from 15, LI to 0, LI step -0.5, L2
from 3, L2 to 0, L2 step -1. Notice how the sound seems to vibrate
as it fades. If you want to hear it again, just hit the option key.
You may want to use that sound in a program you write. At
this point you will notice a Basic subroutine is displayed near the
top of the screen. Make note of it and any other interesting sounds
you come up with. Start a library of subrtTutines. When you're
ready to try a new sound, hit the START key.
There are a few other useful routines in this program you may
want to study. Lines 12 and 14 will show you how to use random
color. You will find extensive error trapping of input routines. The
loop from line 410 to 440 shows how to make use of the OPTION
and START keys. To see if the SELECT key has been pressed,
PEEK at 53279 and see if it ec|uals 5.
When you type in line 340, type those messages using inverse
video. The routine from line 300 to line 380 will cause these
messages to flash. To further dress up your display, I suggest you
also use inverse video for the messages at lines 10, 130, and 6000.
After you've used and studied this program for a while, you
will begin to realize that the variety of possible sounds is almost
endless. Now consider this. You have been using only one of the
four voices available. The four voices can be used at the same time.
You control the volume, pitch, and distortion of each voice. Take it
away, imagination!
REM SOLIfOS PRKRAtI BY JERRY WHITE 8/28
.-'89
1 GRAPHICS = Diri ;^K1>.BL$<20):BL$="
II
3 7:? "PITCH=Alf<' NUMBER FROM 6 THRU 255
118
Programming Hints
.":? "WE WILL mUE T)£ PITCH IN LOOP 2."
4 ? ••? ''L1=0UTER LOOP 1 UOLll€."=? "TYPE
AMY NUMBER FROM 9 THRU 15 AT PROMPT FOR
M. TO, AMD STEP."
5 ? :? "L2=IHNER LOOP 2 PITCH."-? "T'fPE
PtW NUMBER FORM O THRU 255" =? "AT PROMPT
FROM, TO, AlCl STEP"
7 ? •■? "HIT RETURN TO BEGIN"; = INPUT X$
10 GRAPHICS 0:? =? " SOUHD TEST "
12 POKE 752.1:C=Rm(0):^16 = REPEAT=0
14 SETCOLi'JR LC.2^SETC0L0R 2.C.8:SETC0L0
R 4,C.2
IQ POSITION 2.3:? "TYPE DIST ";:TRAP
34=D^PUT D^TRAP 48090
32 IF D=0 OR D=2 OR D=4 OR D=8 OF; D=10
R D=12 OR D=14 THEN 36
34 F'OSITI*^ 2.3:? BLf^GOTO 3«
36 FIJSITION 2.5--? "TtTE PITCH ".;:TRAP
40:INFltT P^TRAP 46800
38 IF P<255 TV€H 42
40 F-OSITION 2.5:? H.$:GOTu 36
42 FWITIOH 2.?:? "TyTE LI FROM ";:TRAP
46:IhFllT F1:TRAP 48009
44 IF FK33 Tf£H 48
4b PCeiTIOH 2.?:? BL*:G0TO 36
48 POSITION 2.9:? "TYPE LI TO "; :TF^'
52:UFUT T1:TRAF' 48000
50 IF Tl<33 THEN 54
52 POSITION 2.9:? BLt-:iJJTO 48
54 PiJSITION 2.11:? "TYPE LI STEP ";:TRAF*
58:INFUT S1:TRAF' 48009
56 IF SK33 TF£N 68
58 F-aSITION 2.11:? BL$:OJT0 54
60 PCeiTIiJN 2.13 = ? "T'tPE L2 FROM ";:TFwF'
64:INFliT F2:TRAF' 48909
62 IF F2<256 THEN 78
64 F-OSITION 2.13:? BL$:|J3T0 68
70 PttBIT ION 2. 15 : ? "TYFE L2 TO " ; = TF^'
74: INPUT T2:TR'AP 48909
72 IF T2<256 THEN 88
74 F■CeITIa■^ 2.15:? BL*:G0T0 76
119
Programmins Hints
88 F-OSITION 2.17 = ? "T'lft L2 STEP ";:TRAP
84=IH='UT S2 = TRAF' 40090
£2 IF S2<256 THEH 188
84 FffilTIW 2,17:? BL$ = iDTO 88
180 IF REPEAT >0 THEN QJSUB 5800 ^GOTO 488
120 G&5UB 5800-5CtiND 0,0.0.0 = ? CHR^dS)
130 ? =? " YOLIR SOiJCl :5UBF:0IJTINE: "
140 ? ■7 "100 FOR: L1=%F1;" TO ";T1;" ST
EP ";S1
160 ? "110 FiDR L2=")F2;" TO ";T2;" STEP
";S2
180 ? " 120 9JUHD 0. " i P; "-L2, " ; D; Ml "
200 ? "130 HEXT L2"=? "140 h£XT Ll"=? "1
50 RETURN"
2-80 FOR DELAY=1 TO S^^HEXT DELAY
300 FOR TIt€=l TO 5:F"u:3ITICW 2.20 = ? " H
IT STAR:T TO RESTART":? " HIT UF'THDM TO
REF'EAT "
320 FOR C£LAY=1 TO 10 = f€XT DELAY
340 POSITIOW 2.20:? » HIT START TO REST
ART":? " HIT OPTION TO REPEAT "
360 FOR DELAY=1 TO ie:b€XT DELAY
388 b€XT TUE
400 Sm\Q 0.0,0.8
410 IF PEEKX 53279 >=b T^CN 18
420 IF F*EEKX 53279 >=3 THEN 508
440 GOTO 410
500 REF"EAT=REPEAT+1:G0T0 180
5000 Fm Ll=Fi TO Tl STEP SI
5100 FOR L2=F2 TO T2 STEP S2
5200 TRAF' 6800:SOUWD 0.P-L2.D.L1 :TRAF' 48
000
5300 NEXT L2:NEXT Ll^RETURN
6000 ? :? " INUALID SOUND, TRY AGAIN.
"=SOUND 0,0,0,0
6100 FOR DELAY=1 TO 258= NEXT DELAY
6110 GOTO 10
120
Programming Hints
Al Baker's Prosrammlng
Hints for Atari/Apple
Al Baker
Exploring joysticks . . .
Programming is the most complex and least organized of human
endeavors. Well, maybe after the U.S. Government and raising
children. Many people have tried to bring order out of this chaos.
In this column, I will join that noble company. With your help, we
just might pull it off.
Two of my favorite computers are the Apple and Atari. They
are superbly designed machines. (It's not that I don't like the PET. I
do. I guess I'm just hopelessly addicted to sound and color, joysticks
and paddles.) In this column, I am going to help you use the sound,
color, and attachments of these two computers.
In each issue, I will show you one or two short routines fully
utilizing some feature of an Atari or Apple. I'll put the routines to
work and leave you with a chance to work on a programming
exercise, answered in the next issue.
I said I needed your help. Send me any routines you have and
would like to share. If I use them, you'll be given credit as the
source.
The Atari Joystick
This month, we are going to explore the Atari joystick. The
position of a joystick is read with the function STICK. The joysticks
are numbered from to 3. Thus, the position of the second joystick
is STICK(l). This function returns the number 15 when the joystick
is centered. Here are the results of STICK for the other joystick
positions.
14
11 ^^^'
13
,6
Prosrammins Hints
The button on the joystick is read with the function STRIG.
STRIG(O) reads the button of the first joystick. The function is zero
if the button is pushed and one if the button is not pushed.
Most programs use the joystick to move objects around on the
screen. As soon as the program needs a yes or no response,
however, the players must use the keyboard. This is inconvenient,
especially when there are several players, none sitting close to the
keyboard. Why not use the joystick to make the selection?
Two Entry Menu Selection
Look at the first listing. This is a routine which uses the joystick to
get a yes or no response from a player. Line 45 turns off the cursor
on the screen. Lines 60 through 140 set the default answer and
display the options, YES NO, on the screen. The default answer, in
this case YES, is highlighted in reverse video.
The routine assumes that the word YES is to the left of the
word NO. If the joystick is moved to the left, then lines 180 through
240 set the answer to Y and highlight the word YES on the screen.
If the joystick is moved to the right, then lines 280 to 340 set the
answer to N and highlight the word NO. Pushing the button ends
the routine. This is handled in line 380. The IF statement is true if
STRIG (PLAYER-1) is 1. Remember that this means the button is
not pushed. The program loops back to line 180 as long as the
button is not pushed.
Lots of lines and REM statements take up memory and slow
the program down. Look at the second listing. Here is a short
program which uses the menu selection routine. The routine has
been compressed into lines 1000 through 1050. The program needs
no explanation. Play it and get some feel for the convenience of
using the joystick instead of the keyboard.
At the tone the number is . . .
Listing 3 is another joystick input routine. This time we are using
the joystick to input a number. It is similar to the first routine.
Lines 60 through 140 set the default input number and print it on
the screen. Notice that line 120 prints a blank after the number.
This prevents garbage from appearing on the screen if 'A' goes from
2 digits to 1 digit.
Look at lines 130 through 140. This generates a muted bell
sound, very similar to striking a xylophone. The SOUND statement
has four parameters. The first is the sound register. This can be any
number from to 3. Up to four sounds can be created at one time.
The second parameter is the pitch of the sound. The higher the
122
Programming Hints
number, the lower the pitch. Using lOO-A gives a pitch that goes up
as A gets bigger and goes down as A gets smaller.
The third parameter is the sound quality. A 10 gives a clear
tone. The fourth parameter is the loudness of the note. The NOTE
goes from 15-0 = 15 or loud to 15 — 15 = or quiet. This creates
the bell effect.
Lines 180 through 240 decrease the input number as long as
the joystick is pushed to the left. Lines 280 through 340 increase the
input number as long as the joystick is pushed to the right. Line 380
ends the routine if the button is pushed.
Conclusion
Next tim.e we will compress the number input routine and use it in a
program. Try it yourself and let's sec who does a better job at
compressing it! We'll also try our hand at using the Apple paddles to
do a menu select.
Al Baker is Programming Director of The Image Producers, Inc., 615
Academy Dr., Northbrook, IL 60062.
Program 1. Two Entry Menu Select
The words in the boxes are typed using the Atari key to put them in reverse
video.
10 REM . . . TlCi ENTRY riENU SELECT . . .
20 REM FROM JOYSTICK
30 REM
40 Re-1
4.3 REM TURN iJFF CURSOR
45 POKE 752.1
47 Rei
50 REM DEFhULT ANSWER-
60 A^-="Y"
70 REM
80 REM DISPLAY MENU
90 REM XY.YY IS POSITION OF YES
100 REM KN..YN IS POSITION OF NO
105 REM
110 POSITION ^y.YY
120 PRINT 'tYESf';
130 POSITION XN.YN
140 PRINT 'W'i
150 REM
123
Programming Hints
160 REh SCAN JOYSTICK FOR YES
170 REM
1S0 IF STICKCFlAYER-DOll THEN 239
190 ft$="Y"
200 POSITHy XY..YY
210 PRINT 'VE^'i
220 POSITION >=;N/i'N
230 PRINT 'Wi
240 GOTO 180
250 R-EM
260 REN SCAN JOYSTICK FOR fd
270 REM
230 IF STICK(PLAYER-1)<>7 THEN 389
290 ftr="N"
300 POSITION XY.YY
310 PRINT "YES";
320 FffilTIOfJ XN.YN
330 PRINT '®'.;
340 GOTO 180
350 REM
3m REM SCAN TRIGGER FOR CHOICE
370 REM
3S0 IF STR IK PLAYER- 1) THEN 188
3SQ Ff M
400 REM WE HAI..E ANSWER
410 REM
420 PRINT A*
Program 2. Do You Love Me?
10 REM . . . DD YOLI LOUE ME ...
20 REM
30 RB1
40 REM DECLARE STRINGS PlC CONSTANTS
50 DIM kS< 1 )
60 Cl=l
70 REM
80 REM ASK MY OUCR IF HE LOl-ES ME
90 REM
95 GRAPHICS
100 XY=12:YY=18
124
Prosramming Hints
110 Xh^24-Yf+=18
120 PLHrER=l
130 POSITION 12.10
140 PRINT "DO Vai LOUE ME"'"
150 bOiiUB 1000
im REN
170 REM RESFtJfCi TO ANSWER
180 REN
190 PCGITIiJf-^ 3.22
200 IF A*="V" THEN PRINT " SHUCKS.. I
LOl.-E VOU TI30."
210 IF R$="N" TFEN PRINT "l€LL.. I LOIE V
OU At-frWAY. (StHPFLE)"
220 FOR 0ELAY=1 TO 1600
230 HEKT DELAY
240 GOTO 95
960 REN
970 REN JOYSTICK ROUTINE
980 REN (DISaiSSiED ELSEWHERE)
990 REN
1000 POKE 752..C1:A$="Y"
1010 POSITION yY.YY^? "^';:P0SITI0N KN
..'I'N^? "NO";
1020 IF STIi:K(PLAYER-Cl>=ll THEN lOOO
1030 IF STia((PLHYER-Cl)=7 THEN A$="N"^P
qSITION KY.YY:? "YES"; ^POSITION XN.YN^?
S'.i -GOTO 1020
1040 IF STRIG(PLhYER-CI) THEN 1020
1050 RETURN
Program 3. Number Select
10
RS1
NLINBER :;
SELECT
20
REN
FRON JOi
fSTICK
30
REN
40
REN
43
REN
TURN
iDFF CURSOR
45
POKE
752.
.1
47
RB1
50 REN
DEFAULT
Af-^SWER •■
60
H=10
125
Programmins Hints
70 REM
80 REM DISPLAY NUMBER-
90 REM X,Y IS POSITION iJF hUMBER
105 REM
110 POSITION x.y
120 PRINT H.:" ";
130 FOF: SND=0 TO 15
135 SCtiND 0..100-A. 10.15-:5fCi
140 h£XT SNO
150 REM
160 REM SCAN JOVSTICK FOR SiLETRACT
165 REM DON'T GO BELOW im LIMIT
170 REM
180 IF STia«FlAVER-lK>ll THEN 280
185 IF A=LiJU THEN 18w
190 A=A-1
240 OJTO 110
250 REM
260 REM SCAfvl ..OYSTICK FOR m
265 F£M DON'T GO ABOUE HIi:H LIMIT
270 REM
280 IF STICKXPLAYER-1)<>7 THEN 330
285 IF A=HIGH THEN 130
290 A=A+1
340 GOTO 110
350 REM
36Q R-EM SCAf^l TRIGGER FOR CHCaCE
370 R-EM
380 IF STR IK PLAYER- 1) THEN 180
390 REM
400 REM WE m..E ANSWER
410 REM
420 PRINT A
126
Prosramming Hints
Al Baker's Prosramming
Hints: Apple and Atari
Al Baker
During games it is often easier to use a joystick than to play musical chairs
trying to share the console between two or more people. The subroutine is
from line WOO up is useful in such applications.
Last Issue: Atari
I left the Atari readers with a problem last time: condense the
number selection routine as much as possible and use it in a
program. If you'd like to share your solution with the rest of us,
send me a listing. My solution is in Listing 1. The program is the
old favorite "Guessing Game."
The routine is condensed into lines 1000 to 1050. I made a few
changes in it to accommodate the game. The main change was to
remove the setup of the variable "A". The rest of the program is the
standard number guessing program. Lines 7 through 23 initialize the
variables, including "A", and lines 30 through 80 pick out a random
number and ask the player to guess it.
Line 90 calls the joystick number selection routine. If the
player makes a correct guess, then lines 200 to 220 tell him so and
loop back for another game. Otherwise lines 1 17 to 140 give him a
Bronx cheer, tell him how he was wrong, and loop back for another
guess.
1 R£M GUESS A M11BER
2 F£M
3 Ff M
5 REM SET UP THE JOYSTICK DATA
6 F£M
7 A=10
10 Lm=i
28 HIL.H=20
21 X=17
23 FlHYER=l
2? REM
23 R£M FlAY THE GATE
127
Prosramming Hints
29 m\
30 GRAPHICS
40 FUSITIffl 2.. 5
50 ? "I hM THIHKIHG of R MJriBER BETICEH"
68 ? im:." ArCi ";HIGH.;". ";
70 ? "WAT IS yOLR GIJESS^"
80 GUESS= I HT( RmC )t20 )+ 1
82 F£H
84 F-EM GET Tl€ FIAYER'S ftilSlCR
8b F£f1
% GttSUB 1800
180 F-OSITim 14.20
110 IF ft=GUESS T^€H 200
112 FS1
114 Fei i«F:OHG GUESS
116 FBI
117 sm-\u ©/Zmi.iy.. 15
118 Fa< 1=1 TO 50-HEMT I
119 SOUtffl 0..0.0..0
120 IF A<OJESS THEH ? "TRY HIGHER"
130 IF R>QJESS THEH ? "TRY LCHCR "
140 GOTO 90
170 Fei
180 F£n CWSECT GLESS
190 REM
280 ? "YOU GOT IT"
218 FOR 1=1 TO 500:h€MT I
228 GOTO 38
978 REM JOYSTICK MJMBER SELECT
980 REM (DISCUSSED LA:5T ISSUE)
998 REM
1080 FIJKE 752.1
1018 FCESITirH X/y':? A;" ".-FOR Sm=0 TO
15 ^SiXlND 0. 100-A.. 10.. i5-SHD ■■ t£XT SHD
1020 IF (STICK(PLAYER-1)=11>^<A>L0W) THE
H A=A-1=G0T0 1010
1830 IF (STICK(PLhYER-1)=7>:^:(A<HIGH:j THE
N A=A+1=G0T0 1010
1040 IF STRIGc PLAYER- 1) THEH 1828
1058 RETURN
128
Programming Hints
Error Reporting System
for the Atari
Len Lindsay
One of the disappointing aspects of the Atari Computer System is
its lack of user-oriented messages. Particularly clisturbing is the error
message, or should I say error number? It stops and tells you
ERROR 138
What? Where did I put my manual? You then search through your
desk, find the manual, flip pages until you hit the error messages,
and look up number 138. If you have a disk system, the following
program will do all the work for you, as well as offer you several
options for continuing program execution. (Non-disk users will also
find several aspects of the program suitable for use without a disk).
Here is what the program does for you each time an error is
encountered:
1) It reports to you that an error was encountered and gives
you the error number and the line number where the error
was encountered.
2) If you have an error messages diskette in drive 1 it will next
print out an error message in plain English, telling you what
went wrong and possibly how to correct it. (Without a disk
you won't get this message but all the rest of the program
works fine).
3) It offers you the choice of ending program execution or of
continuing in one of three ways:
a) continue with the line on which the error was encountered.
b) continue with the line immediately following the error line.
c) continue with the LINK line (equivalent to the TRAP
function).
That is the system in a nutshell. It is structured to be of general use
and should be modified to your particular needs. To aid in this, I
will explain how the program works.
Program Explanation
LINE is the required DIM statements for string variables used in
the system.
LINE 1 sets the TRAP to 32500 — the start of the reporting system.
129
Programmins Hints
NOTE: The TRAP command cannot be used in your program.
Instead, simply set the variable LINK to the line you normally
would have used for TRAP. Example:
250 TRAP 5000
should be entered as:
250 LINK = 5000
LINE 32500 finds the line number in which the error occurred. It
also finds the error number.
LINE 32510 prints the error number and the line at which it
occurred.
LINES 32520-32530 assigns a file name to be used to recover the
appropriate error message from disk.
LINE 32540 sets a TRAP to report a default message if an error
occurs while retrieving the error message (for instance, if your disk is
turned off, or if you have no disk).
LINE 32550 opens the appropriate disk file and, if successful, skips
over the default message.
LINE 32570 gets the error message from disk.
LINE 32580 jumps to the subroutine to find what the next line
after the error line is. It also resets the TRAP for future operation.
LINES 32581-32587 print your options.
LINE 32588 ask for your choice.
LINE 32589 clears the screen.
LINE 32590 turns off the TRAP and ENDs if you hit "S" (for
STOP).
LINES 32591-32593 check for other legal choices and go to the
appropriate line.
LINES 32599 jumps back to print your options once again if an
illegal entry is detected.
LINE 32600 starts the routine to find the next line number after
the error line. The variable NXLINE is initialized.
LINE 32610 finds the first line number in the program.
LINES 32620-32660 finds the line number by starting at the first
line and checking one line at a time until it hits the error line. The
next line is then used for the next line number.
LINE 32699 Returns back to the line calling this routine.
That's it!
130
Programming Hints
DIM ERt-O1$(5>.ERFILEfa2).XH$(l0y)
1 TRAP 32500 ■F£M TO ERROR REPORT ROUTIrE
2 REM tU ERROR REPORT SYSTEfl by
3 REM tU LEN LlhOSHv (C) 1386
4 REM YOlj:: PROGRAM GOES HERE
5 REM SET UARIABLE LIHK TO THE
b REM ^GIHHIHG LlhlE OF YOUR MCOJLES
7 REM - h€EDS A DISKETTE IN DRItE 1
8 REM WITH ERRiiR FILES CREATED WITH
9 REM THE ERROR FILE WRITING PROGRAM
10 REM THhHK YOU TO COfFUTE; IRIDIS. hHD
ATARI FOR INFO LGtO IH THIS
32500 ERLIHE=25b:^;^PEEK'. 187 hPEEK' 18b ;■ ■ ERM
UM$=STR$(PEEKa95);-REM ERRiJR REPORT SYS
TEM
32501 REM nt HEEDS ^ DIM ERHLitmS)
32502 REM Ut DIM ERFILEJi 12'
32503 REM tU DIM KAfa*:'
32504 REM tU USES SUBROUTINE 32bOy TO F
I NO t€XT LINE
32510 PRINT "}ERRiJR NUMBER ".lERNHU ; '^ IN
LIh€ "jERLINE
32520 ERFILEI="D^ ERROR"
32530 ERF I LE$( LEhK ERF I LEI )+ 1 )=ERNUMI
32540 TRAF' 32560
32550 iPEN tt5.4;y.:ERFILEJ-G0T0 32578
32560 PRINT "ERROR HIMEER " lERNiifil.: '^ IS
NOT m FILE" GOTO 32580
32570 It^PUT #5iXHl PRINT XhI- CLOSE #5
32580 GCfSLE 32600 -TRAF' 32500
32581 F-RINT " SHALL I "
32582 PRINT " STiDF'"
32583 PRINT " OR: "
32584 PRINT " CONTINUE WITH ■■ "
32585 F-RINT " ERROR LINE "lERLINE
32586 PRINT " NEXT LINE ".NXLINE
32587 PRINT " LINK LINE ";LINK
32588 PRINT " l^iHICH CHOICE"; INPijT XAI
32589 PRINT "}"^REfi CLEAR SCREEN
32590 IF :->H$="S" Th£N TRAP 345^7 ^S^OP
32591 IF XA$="E" THEN GOTO ERLIIC
131
Prosramming Hints
32592 IF XRJ="H" THEN GOTO NXLINE
32593 IF XH:f="L" TF€H GOTO lIHK
32599 iJJTO 32581^ REM INUALID RESPONSE
32606 H/a_INE=y^REM FUd HFKT LU£ HUnBEP
32601 REM tn ERLIHE IS INPUT TO THIb
ROUTINE AS THE LR€ NUMBER
32602 PEN nx NXl.INE IS RETURhED hS THE
NEXT LINE NUmER
32605 REt1 tU BASED UN COfiPUTE #4 PAGE 3
2 PROGRAM LIST in:
32610 hODRESS=PEEk:': 13f .:'+PE£K' I37):v;25if KE
f1 GET THE FIRST LINE NUnBER
32620 LINE=PEEK': hDDRESs i^pEEK ■. hOORESS+1 :'
*256
32630 IF HXLIHE=1 THEN HXLINE=LInE^GuTO
32699
32640 IF LINE=ERLINE THEN HXLn€=l
32650 h£)OR:ESS=AODRESS+PEEK^ HDDRFSS-t-2 )
32660 GOTO 32620
32699 RETURN
In order to fully use the Error Report System you must have a
diskette with all the error messages correctly recorded on it. The
following program can be used to create your own custom-made
error messages master diskette. It simply asks you for an error
number and its matching message. The message is then written to
disk under the appropriate error number file.
REM nt ERRiDR REP-OFlT WRITER
1 REM nt <C) 1980
2 REM tU LEN LlhDSAY
3 REM tU PUTS ERROR INFO TO DISK
10 DIM ERMJM*(5)..ERFILE$(12).XA$(ly0)
90 PRINT "}":REt1 CLEAR SCREEN
100 PRINT "WRITE ERROR tlEANINGS TO DISK"
110 PRINT " GET CHJT YOUR: ERR:UP LIST - LE
IS GO-"
120 TRAP 120^ PRINT " WHAT IS THE NEXT E
RROR NUMBER " . ■■ UPUT ERHUf-U
125 E=UAL(ERNUnf):TR-AF' 34567
132
Programming Hints
138 ERFILEI="['-ERRC!F:"
140 ERFILE$( LEH': ERF I LEI )+l >=ERfM1$
150 PRII-n" " PLEhSE TYPE IH ITS MEhNING
t HINTS" ■■ INPUT Xftr
160 OPEN #L8;i3..ERFILEf
170 PRnrr "}HUI-j I-^ITIMi: error HiUBER ".;£
RMUr«
180 PRIhrr #1;XA* CLOSE #1
130 GiJTO 120
Possible System Uses or Modifications
The error reporting system can be used while developing your
programs, providing you with mcsiages during your next run as well
as with several restart options. The system is presently under
manual control after an error is encountered. This of course can be
automated to provide error trapping AND error correction.
For example, your program may provide a hardcopy printout
of the program results. If an error #138 is encountered, you may
wish to print a message on the screen such as "Please turn on the
printer" and then go back to the offending line. Print a cursor-up
after the message and you can loop until the printer is turned on,
after which the program immediately continues executing.
You may also be able to use pieces of this system in your own
programs. For example, lines 32520-32530 show how your program
can dynamically create its own clisk file name, based on the value of
variables.
133
134
CHAPTER FIVE
Applications
135
Applications
Atari Tape Data Files:
A Consumer Oriented
Approach
Al Baker
This complements Larry Isaacs' article "Inside Atari BASIC." The
technique presented here is very useful for cassette users.
Introduction
This article is based on a major axiom of consumer computing:
Easier is Better
The specific corollary when writing a program which saves data
between program runs is:
Use only one tape. Program and data should be on the same tape.
They should, in fact, be the same thing.
A consumer should be able to load his program, run it to update his
checkbook and balance his budget, and then save the program on
tape when done. The next day, he can load his program and all
data changes from the previous day should be there.
"Impossible," you say? Well, perhaps. It is certainly impossible
on some of the computers on the market. But it is not impossible on
the Atari. The trick is to fool Atari Basic into saving all
dimensioned variables when a program is saved to tape. We won't
try to save the simple variables. Since I am not a revered expert, 1
won't make the mistake of saying this is impossible. (But, I think it's
impossible.) Saving the dimensioned variables with a program is
relatively easy.
Write Your Program
Listing 1 is a simple program. Nothing tricky. But notice that I print
the dimensioned variables in Lines 70-130 and then assign values to
them in Lines 140-190. I am assuming the variables have valid
contents before changing them! The only important restriction here
is to type the line containing the DIM statement first. It doesn't
have to be the first line in the program. Just make sure it is the first
line typed.
136
Applications
The Atari Basic variable symbol table is constructed when
each line is typed in, not when the program is run. Later we will
need to find the locations of the string variables in the table. This is
easier if they are the first variables present. For a more complex
discussion of the symbol table, see the text in the box.
50 DIM A?(10) ,B(2,3)
70 ? A$
80 FOR 1=0 TO 2
90 FOR J=0 TO 3
100 PRINT B(I,J) ,
110 NEXT J
120 PRINT
130 NEXT I
140 ? "STRING="; : INPUT A$
150 ? "I="; : INPUT I
160 IF 1=9 THEN 200
170 ? "J=";:INPUT A:B(I,J)=A
190 GOTO 15
200 END
Suppose the program is already written and you didn't type
the DIM statement first. Write your program to tape using the
command LIST"C". Type NEW. Now type the DIM statement from
your program with the string variables first. Finally, reload the
program from tape with the command ENTER "C". Now the string
variables are at the beginning of the variable tables.
Protect The Dimensioned Variables
The next step is to fool Basic into treating the dimensioned
variables as part of the program. Also, you have to add the code to
let the program save itself to tape. In an application, saving the
program to tape will be the final program option selected by the
user. In Listing 2 this is added to the program in lines 200 through
230.
50 DIM A$(10) ,B(2,3)
70 ? A$
80 FOR 1=0 TO 2
90 FOR J=0 TO 3
100 PRINT B(I, J) ,
110 NEXT J
120 PRINT
130 NEXT I
140 ? "STRING="; : INPUT A$
150 ? "I="; : INPUT I
160 IF 1=9 THEN 200
170 ? "J=";:INPUT A:B(I,J)=A
190 GOTO 150
200 A=PEEK(140)+PEEK(141) *256
210 A=A+82
220 POKE 141, INT(A/256) :POKE 140 , A-PEEK (141 ) *256
230 CSAVE _
137
Applications
Locations 140 and 141 contain the address of the end of the
computer program. Program line 200 places this address in the
variable A. In line 210 we add the size of the dimensioned variables.
Each string variable contains as many bytes as its dimension. Each
numeric array contains 6 times the number of members of the array.
The B array is 6x(2+ l)x(3+ I) = 6x3x4 = 72 bytes. Thus we had to
add 10 + 72 or 82 to the end of the program in the example.
Now run the program and let the internal CSAVE create a
tape. Turn the computer off and then on. Now reload the newly
created program from tape. For some reason this step is important.
(I don't know why.) If you do not use the new tape, this procedure
won't work.
Finish The Program
We now have a program in memory which has an invalid program-
end pointer. See the third listing. Add lines 10 through 40 to your
program. Make sure that you use the correct number instead of
"-82" in line 10. Remember that this number is the size of your
dimensioned variables.
Refer to Table 1. Locations 140 and 141 form the program-end
address. Locations 142 and 143 form the stack address and locations
144 and 145 form the pointer to the end of memory used by the
program. The RUN command sets all of them equal to the incorrect
end-of-program pointer. Lines 10 through 40 correct them.
Here comes the only hard part. You are going to have to PEEK
around in memory. The RUN command sets the length of all
Table L
These two byte addresses point to important areas used by Atari Basic.
Use this To get the location of this
PEEK(130) + PEEK(131)*256 Variable name table
PEEK(134) + PEEK(135)*256 Variable value table
PEEK(136) + PEEK(137)*256 Beginning of program
Use these only when program running
PEEK(140) + PEEK(H1)*256
End of program and beginning of dimensioned
variables
PEEK(142) + PEEK(143)*256
End of dimensioned variables and beginning of
stack
PEEK(144) + PEEK(145)*256
End of memory used by program
138
Applications
strings to zero. You must repair their lengths if you want to save
string data.
Table 2.
The variable name table; Entry lengths are different. Box symbolizes that 128
is added to ACSII value of last character to show the name's end.
Variable
Variable
name
ABl
AB [T]
3 chiiracter numhcr name
AR(3,4)
AR E]
2 character array name
CDOG(17)
CDOG n
4 character array name
ALPHA$ (10)
ALPHA $\
6 character string name
E
m
1 character numlicr name
FIG
FI O
3 character numiicr name
Note: Variable names can be up to 120 characters long and are completely unique.
Variable ABC is different from variable ABCD. Variable names DO NOT appear
in the program in memory. Only a 1 byte pointer to the variable name in the
variable name table appears.
Look at Table 3. The third entry in the variable value table
is the string ALPHA$. Its current length is 5+0*256 or 5. These
two bytes must be set to the correct length of the string. Type
command: PRINT PEEK(134) + PEEK(I35)*256. Now you know
where the variable value table is. If you have been writing the
program in the listings, you should get the answer 2056. Assuine the
string is the first entry in the table. The location of the length is
2060 and 2061. Since the length of the string of data being saved in
the example is 10, I set location 2060 to a 10 in line 60 of the
program.
Try it out
The program is complete. SAVE it. Now RUN it. You will probably
get garbage in the printout. Put a 10 character string in the string
variable. Now put numbers in various entries in the B array. Typing
a 9 for the I subscript will end the program with a CSAVE. Do this
CSAVE onto a new tape. Turn the computer off and on. Now load
this new copy of the program and RUN it. Viola! The data is still
there! Now just imagine that this was your budget information,
address book or other files. You have a no-hassle, one-tape system.
Conclusion
I have provided more information about the internals of the Atari
139
Applications
T1
O
H
3-
13
O
P
-a
X
n
>
> <
H
a
7a
m »
L»J
— ' >-i
;;*;
^
§.
n
,
ho
3
03
3
3
P_
nj
3_
1^
On
-t-
3^
"^
00
+
+
+
On
ON
ON
3
-1^
OJ
\
^
+
^
h~>
hJ
00
00
\
^^
^
^J>
00
0\
00
Si- 3
c c
H
^1 r^ —
J. to t J
+ COO)
* + g
H '^ "
p' tr P"
H
00
+ K-
3
ft
ID
+ -a
X
^'
r-f
^
3
13
£l;
3
+
Q
-1
q
U3
rb
n>
3 '-•'
P n r1
M It P-
P 3 ES'
a. ™ B
u. S P
+ 5' Si
o 3 q
On P" ,
. TO
r, „ p
p^ -1 (/>
rt rL r-t
u, i^ P-
3. hS
3 :r -■
o 3 c^
+ M 2
T^ P ru
O ■-• p
* :r" ^
r-o nj O-
ON
o
'S s
3
=^3
O.
£2
p;"
-^
n
s •
d
ft
^ fr
3 jrj
3
3- + _.
s * -^
O ^'
3 ON CT
g ^ &-
"-* II rt
^ c -X
5 o ^
3^5
• g- 3
ft ci-
g -
ft 2
5' °
3 3
< 5"
EL'S
S- w
140
Applications
than is really necessary to solve this problem. If you are interested in
this kind of information, study it. If not, skip it. If you have any
questions, I would be glad to answer them. One warning. Do not
press break while the program is running and then type RUN.
Always use the CONT command after pressing BREAK. Otherwise
the statements in lines 10-40 will destroy the program data. This can
be prevented if you know what the correct value of A should be in
line 10. Replace line 10 with 10A = n, where n is this number. Do
this for your finished product.
10 A=PEEK(140)+PEEK(141) *256-a2
20 POKE 141, INT{A/256) :POKE 140 , A-PEEK ( 1 41 ) *256
30 POKE 143, INT(A/256) :POKE 142 , A-PEEK ( 1 43 ) *256
40 POKE 145, INT(A/256) :POKE 144 , A-PEEK ( 145 ) *256
50 DIM AS(10) ,B(2,3)
70 ? A$
80 FOR 1=0 TO 2
90 FOR J=0 TO 3
100 PRINT B(I, J) ,
110 NEXT J
120 PRINT
130 NEXT I
140 ? "STRING="; : INPUT A$
150 ? "I="; : INPUT I
160 IF 1=9 THEN 200
170 ? "J=";:INPUT A:B(I,J)=A
190 GOTO 150
200 A=PEEK(140)+PEEK(141) *256
210 A=A+82
220 POKE 141, INT{A/256) :P0KE 140 , A-PEEK ( 141 ) *256
230 CSAVE
Changing Atari programs to save the
dimensioned variables:
. Get the program working.
. Place the string variables at the beginning of the variable table.
. Change the program so that it internally points the program-end
address past the dimensioned variables and then saves itself to
tape.
. Run the program, creating a copy on tape.
. Turn the computer off, on, and then reload the program.
. Add the statements to the beginning of the program to correct
the program-end pointer, stack pointer, and end-of-memory
pointer.
. Add the code to restore the actual string variable lengths to the
variable value table.
. Save your finished program to tape.
141
Applications
The ATARI BASIC
Symbol Table
Most BASIC interpreters assign values to the symbol table as the
program is run. Not true with the Atari. New variables are placed
in the symbol table when the program line they are contained in is
first typed.
If you later change variable names, the old variable names are
not removed from the table. They stay forever! Even the CLR
command does not remove them.The continue to take up room.
How much room? Eight bytes plus the length of the name. Add
another byte if the variable is an array.
Fortunately, it is possible to clean up the variable table. Write
the program to cassette using the command LIST "C", type NEW,
and then reload the program from tape with the command ENTER
"C".
A program can often be made to run faster by placing selected
variables at the beginning of the variable table. This decreases the
time it takes to find variables which are used in time-critical
routines.
To place these variables at the beginning of the variable table,
write the program to cassette using the command LIST "C" and
then type NEW. Now use those variables. For example, if the
variable A must be the first variable in the table, type A = 0. If the
string B$ must be used, type DIM B$(l). You are "ordering" the
variable table. When you have finished placing as many variables in
their correct order as you want, load the program you saved to tape
with the command ENTER "C". This does not interfere with the
contents of the variable table.
142
Applications
Figure 1:
BASIC Program Memory Layout
System and
Basic overhead
Variable name
table
Variable
Value table
Programi
Dimensioned
Variables
Stack
Unused
Scr
143
Applications
An Atari BASIC Tlitoriah
Monthly Bar Graph
Program
Jerry White
Atari sound and graphics are great for game programs. In this
monthly graph program, you will see how they can also be used to
display data.
Data is often processed and compared on a monthly basis.
Reports are generated to monitor things like cash flow or
production. Sometimes it is much more meaningful to see totals in
bar graph form rather than trying to compare a list of numbers.
Using this program, the user types in the monthly totals and the
program converts these figures into a beautiful graphic display.
For those who like to know how programs work: I'll break this
one down and explain what each section is doing. For those who
don't care; just key in the program and input your totals next to the
appropriate month. The program will do the rest.
We begin by dimensioning A$ for use as a work string and two
numeric arrays to hold 12 items. We go to the subroutine at 2000
and get our monthly totals and return to line 4. Here we get into
graphics mode 6 with the text window at the bottom. We position
our graphics window X and Y coordinates using PX and PY and put
our heading into A$. Now we're off to the subroutine at 20. We will
use this routine to convert our scratch string so that we can put text
in the graphics window. Returning to line 8 — we use color 1 and
draw a large rectangle. This is where we will draw our data bars. At
line 100 we determine the highest amount (HAMT) so that we can
base our key on that figure. The key will give meaning to the
lengths of the bars. We set Jl = HAMT divided by 65 which is the
length of the longest bar that fits into our rectangle. At line 130 we
determine the top position of each bar. Then we make the top key
figure (K) into a one or two position number and compute the
numbers that will appear along the left side of the graph. At line
240 we begin to position and place our key of the screen. Then we
set the screen margins as wide as possible and put the abbreviations
for each month in the text window directly below the bar it
represents. At line 310 we begin to draw our bars.
144
Applications
Being quite fond of sound, I couldn't resist adding line 360 as a
finishing touch. This loop creates a tone as each bar is completed.
Our purpose was to display data. Why not let the user use his ears
as well as his eyes? Before we exit — we set the screen margins back
to normal and loop at line 500. You could replace 500 with an end
or exit routine. If you remove the first "? :" from line 300 there will
be one line left in the text window for a message.
3 REM HONGRhPH RE'.'. 2 JERRY WHITE
1 REM FOR COriPLITE TUTORIAL
2 Din h*(20>.hNT(12), JW(12):eOSUB 2600
4 GRfiPH I CS b : SETCOLOR 2,4,4: SETC OLOR 4 , 4 , 4 : Z= 1 : SETCOLOR 0,1,10
6 PX=4:PY=0:h$=" MONTHLY GRAPH": GOSUE 20
3 COLOR Z:PLOT 1 S , 9 : DRhWTO 158, 9: DRAWTO 158, 75: DRAWTO 18,75:
DRAWTO 18,9
10 GOTO 100
20 DL=PEEK ( 560 > +PEEK ( 5fc. 1 > *25fc. : D 1 =PEE[:: < DL+4 ) +PEEK ( DL+5 ) *256
22 FOR U=Z TO LEHCA*) : D2=57344+( (ASC(AI^(U, U> )-32)*8) :
[;:.-s=[j1+PV+20+P:k:+U-Z:FOR JZ=0 TO 7
24 POKE D3+JZ*20,PEEK(D2+JZ>:HEXT JZ:NEXT U: RETURN
100 FOR HON=Z TO 12: IF AMT(t'10H:> >HAf'1T THEN HANT=hMT<MON>
110 NEXT MON
120 Jl=HAMT-65
130 FOR NON=Z TO 12: TAHT=75-<hMT<M0N> ■• Jl ;. : JW(t'10H> = IHT<TAMT:> :
NEXT mii
140 IF HANT>= 10000 THEN K=INT(HANT lOaO) : SOTO 200
150 IF HAMT> = 1000 THEN f::=INT(HAMT. lOO) : GOTO 200
160 IF HAMT>=100 then K=INT(HAMT.-10>:GOTO 200
170 t>INT(HHMT)
200 K[::'=K.-5 : K2= I NT ( K-KD ) : K3= I t)T < K- ( KD.+:2 > )
220 y'A = l NT ( f; - ( f^:D*3 > ) : K5= I NT ( K- ( f<D+4 > >
222 Af=STRf ■::K):PX=2-LEN(A*>:P'i'=10:QOSUB 20
224
IF K<5 OR K>99 THEN 280
240
Ht=STRf (K2) : PX=2-LEN'::A*> : PY=24: GOSUB
20
250
A$=8TR$';K3) :PX=2-LEN(A$> : PY=38: GOSUB
20
260
A$=STR* a<4 > : PX=2-LEN ( Rt > : PY=52 : GOSUB
20
270
kt-BTRi ( K5 > : PX=2-LEN < Rt ;■ : PY=66 : GOSUB
20
280
POKE S2,0:POKE 33, 40: POKE 752, Z
300
? :? " K T F H A tl J J A S
N
302
? " E A E A P A U U U E C
E
304
? " Y N B R R Y N L G F' T
1,1
c
310
FOR MOH=Z TO 12: JY=NON-Z
312
PLOT 18+'; JY* 1 2 > , JW ( MON ':>
3 1 4 DRAWTO 25+ C JY* 1 2 J , JW ■; MON >
320 C'RAMTO 25+';jY*12),75
330 DRAWTO 13+<.IY*12> , 75
340 POSITION 18+CTY*12>, JW<MuN>
350 POf ;E 765 , 3 : X 1 1 S , #6 , , , " S : "
360 FOR *.'nL=10 TO STEP -1:S0UND 0,JW<HuN) , lO, VOL: NEXT VOL:
NEXT MON
400 POKE 32, 2: POKE 33,39
5010 GOTO 500
2000 GRAPHICS 0: SETCOLOR 2, 0, O: SETCOLOR 1 , 0, lO: SETCOLOR 4,0,0:
POKE 752, 1
2080 ? : ? , " MONTHLY GRAPH "
2100 ? :? " TYPE AMOUNTS FOR EACH MONTH: ":?
145
Applications
Z120
l'2'9y
221(3
2220
L'238
2240
2258
2260
2270
22c;0
22'?0
2300
2310
2400
TRhF
TRAP'
TRAP
TRRP
TRAP
TRAP
TRAP
TRAP
TRAP
TRAP
TRAP
TRAP
RETU
DO HOT
2200:
2210:
2220 :
22'^0:
2240:
2250:
2260:
2270:
2280:
2290:
2310:
Rf-I
USE NEGATIVE AMOUHT'E
■"• ,
'JAH='
"FEB=
V
"MAR=
"APR=
■? ,
"HAV=
V
"JUN=
V
" JlJL=
"AIJG=
"■E:EP =
"ni::T=
"Hnu=
•' .
"DEC-
INPUT
INPUT
INPUT
I HFin
INPUT
INPUT
INPUT
INPUT
INPUT
INPUT
INPUT
INPUT
JAN: ANT
FEB:AMT
NAR:AMT
APR:AMT
NAV : ANT
..TUH:AMT
JUL:AMT
AUG:hMT
3EF:aMT
Ui::T:AMT
Nu'v':AMT
DEC:AHT
JAN: TRAP
^FEB:TRAP
^MAR:TRAP
:APR:TRAP
^NAY:TRAP
^.TUN:TRAF
^JUL:TRAP
=AUG:TRAP
:SEP:TRhP
=ur:T:TRAR
'=NO'v':TRAP
|=DEC:TRAP
40000
40000
40000
40000
40000
40000
40000
40000
40060
40000
40000
40000
146
CHAPTER SIX
Peripheral
Information
147
ipheral Information
^Adding a Voice Tt'ack
to Atari Programs
John Victor
This technique shows you how to let your Atari talk — that is, play audio
cassettes totally under the control of your program.
We recently had a chance to see the latest in audio-visual
technology — a video tape machine being controlled by an Apple
computer. The student was shown selected film sequences on the
video tape. Then the video tape would stop and the student would
be asked questions by the computer.
This demonstration had some impressive features, but the most
important was the integration of voice with the computer question
and answer technique. The same effect can be generated on an
Atari 400 by combining text, graphics, animation, and color with a
sound track recorded on an audio cassette. And the Atari 400 is
significantly cheaper and easier to program than the combination
video tape player/computer.
There are several ways that a software designer/programmer
can sync a cassette voice track to visuals on the computer screen.
The cassette player that plugs into the Atari computer records and
plays in a stereo format. The right track on the tape records and
plays digital information (such as programs or data files), while the
left track plays audio recordings. The "Talk and Teach" ROM and
tapes supplied with Atari computers use both tracks simultaneously.
As the voice explains material, ASCII characters are read off the
digital track and shown on the screen. The two are coordinated in
the manufacturing process so that they are always synchronized.
The problem with the "Talk and Teach" system for the
average Atari owner is that the development of the Talk and Teach
cassettes requires different hardware than is supplied with the Atari
system. In fact, the system may be developed and run on non-Atari
equipment — we have seen the cassettes run on a modified TRS-80
computer.
The simplest and most practical method for Atari users to sync
voice with their own educational programs is to use a "timed-
BASIC" method. The visuals are programmed into a BASIC
program and run simultaneously with an audio tape cassette. The
148
Peripheral Information
program would then start and stop the Atari cassette player and
change the visuals on the TV screen based on timing routines built
into the program. The key to making this system work is that the
audio tape must start at the same point each time it is used.
The computer course designer-programmer first writes a script
as though he or she were producing a sound/filmstrip presentation.
The spoken words, music, etc. would be specified along with a
detailed description of what is to appear on the TV screen. The
designer-programmer then writes a BASIC program that will
produce the desired visual effects.
The next step is to coordinate the voice with the visuals. The
best way to do this is to have a preliminary routine within the
computer "freeze" each screen display until the programmer hits the
'RETURN' key. This can be done by sending the program to an
INPUT subroutine, but this has the undesired side effect of printing
an extraneous question mark on the screen. We prefer using the
subroutine shown below since it prints nothing at all on the screen:
5000 IF PEEK(764)< >255 THEN POKE
764,255:RETURN
5010 GOTO 5000
Memory location 764 indicates whether a key has been pressed. If
no key has been pressed, the number 255 will be stored there. When
a key has been pressed, the routine sets the value back to 255 (to
keep the computer from printing the key press) and the program
returns from the subroutine.
The designer-programmer should read through the script and
manually check the screen changes to see that the BASIC program
and the script match up and produce the desired results.
The third step is to place timing routines into the program so
that the visuals will be in sync with the recorded voice. We do
NOT recommend using FOR . . . NEXT timing loops for these
routines. FOR . . . NEXT loop timing is not linear on the Atari.
This means that the Atari might take one second to count from 1 to
300 in one loop, and less time to do the same count in another loop
of different length. In addition, the length of the program and
position of the subroutine also affects the count.
Fortunately, the programmer can utilize a built-in clock used
by the Atari computer to count the scan lines in the TV display,
which is stored in memory locations 18, 19 and 20. Location 20
counts in "jiffies" or 1/60 second. Each 1/60 increases the value
stored in location 20 by 1. When the count reaches 256, the value is
cleared to and location 19 is incremented by 1. It takes the
149
Peripheral Information
computer about 4.27 seconds to count from 1 to 256 in location 20,
and about 18.2 minutes to cciunt from 1 to 256 in location 19. You
can watch this process with the following program:
10 PRINT PEEK(20), PEEK(19), PEEK(18):
GOTO 10
The results from these PEEKs could be converted to seconds, but we
prefer to work in jiffies, which requires less math on the computer's
part.
SECONDS = (PEEK(19)*256 + PEEK(20))/60
JIFFIES = PEEK(19)*256+ PEEK(20)
We recommend that at this point the designer-programmer makes
the final audio cassette that is to go with the computer program.
The program can be timed to this cassette, and, if all copies of the
cassette can be made to use the same starting point, then the
program will work with all copies as well.
The task now is to figure out the timing for each change so
that the changes will be made in sync with the audio cassette.
Figure 1 shows a program that we developed to automatically make
these measurements for an audio tape. The user puts the audio tape
in the Atari cassette player and rewinds it to the very beginning.
With the play button depressed, the user runs the program. Line 20
starts the cassette player, and the program begins timing. At each
point where the user wished the computer to change the visual (in
conjunction with the voice), the user hits the 'RETURN' key. At
the end of the program the cassette is shut off, and the user is given
the times between each point on the voice track where the
computer is to change the visual.
The user should note that memory locations 19 and 20 are set
back to after each timing, and that line 55 looks specifically for an
input from the 'RETURN' key. This program counts up to 15
changes, but this number can be increased by increasing COUNT
in lines 40 and 100.
The last step is to insert the time values into the computer
program and to check to see that the voice cassette works in sync
with the program. Figure 2 shows a program that we wrote to
illustrate how timing values can be coordinated with a teaching
program and audio tape. Line 50 of the program defines the
subroutines, of which there are three: one to print questions on the
screen, one to time the visual so that the voice on the tape can read
the question, and one to shut off the tape so that the student can
answer the question just asked.
The QUESTIONASK subroutine in lines 4000-4030 gets its
150
Peripheral Information
information for each question from a DATA line, which includes
question number, screen color, answer to the question, number of
lines to be read, and the lines of text making up the question. After
printing the question, the program sets the time value for the voice,
and goes to the clock subroutine at 5000-5020. When the correct
time elapses, the program goes to the QUESTIONANSWER
routine. Here the tape is shut off, and the user is required to answer
the question. Upon answering, the tape is turned back on.
The time values in this program are based on our own personal
reading of the questions.
While it is possible to record both programs and audio on the
same cassette and still utilize the method we have described here,
the best way is to record programs and audio separately. Ideally, the
programs would be stored on disk and the voice on cassette.
It is possible that with very long audio cassettes the computer ■
and tape will get out of sync due to small variations of the cassette
player. The designer-programmer can correct for this by
occasionally having the student press 'RETURN' when he or she
hears a beep on the audio track, This gives a frame of reference for
the program timing to match up to the tape. The least obvious way
of doing this is to have the student press 'RETURN' before
answering a question.
Figure 1
5 REM TimUG PROGRAM B"/ -OHN UICTOP: .
6 REM FOR AT«?I COtlPUTER Id ICE TRACK-
IB DIM Tir€(15).H*(i:'
28 POKE 54018.. 52 ^REn TURU OH CASSETTE
38 GRAPHICS e^POSITIOT^ 2.. 6
35 PRINT ".START COLlNTIhC. .."
40 FOR C0UWT=1 TO 15 S-ETCOLOR 2..INT(RHD':
1>*15).4
50 POKE 19.0^ POKE 20.. 8
55 IF PEEK-: 764)012 THEN 55
60 J I FFY=256*PEEK( 1 9 )+PEEK( 20 :- T I rE( COLW
T)=JIFFY = PRINT "CHAhlGE #%CnUHT
73 POKE 764 ..255
75 NEXT COUNT
78 POKE 5401 8. 60: REM SHJT OFF CASSETTE
80 PRINT : PRINT "PRESS RETURN TO SEE TIM
E UALLES IN JIFFIES"
90 INPUT A$
151
Peripheral Information
100 FOR courr=i to is^r^int "cham:e #".;C
OIKT ;"=",; T I rE( COUNT ) ■■ NEKT COUNT
200 END
Figure 2
10 REM DEMONSTRATION OF ATARI TIMIhC
28 REM FOR TUTORIALS USIhffi ItQICE AND
30 RBI TIMING LOOPS
40 RB1 PROGRAM DESIGN. U€.
50 CLOCK=5000 ■■ QUEST I ONHSK=4e09 ■ QLEST I ONA
MSWER=3000:REM SUBRGUTIhC LABELS AND LOC
ATIONS
60 D I f1 ANSl€R$( 10).. RESFiiNSEJC 1 6 ) .■ L I \£P: 4
0>
100 GRAPHICS 2+16 ^POSITION 0.2^PF:INT #6;
" BASIC TUTORIAL" ^ PRINT #6; " DENONST
RATION" = PRINT *6
105 PRINT #6j " with wice"
110 TinE=300:GOSUB CLOr:K
200 GRAPHICS 0: PRINT = PRINT
205 PRINT "This is at demonstration of th
e ATARI" ^ PR I NT "computet- 's ability to ut
ilize a"
206 PRINT "sound-'joice track. I wiH as
k four":PRIhTr "sample =iue5tiun5 about AT
«?I BASIC. "^PRINT
207 PRINT "Place audio cassette in playe
r and " ^ PR I hTT " rm i nd to bes i nn i ns " ^ PR I H
T
210 PRI^^^ "Before startins this 6iu)cristr
ation^ "
215 F-RIhrr "nake sure that the PLAY botto
n is"
220 PRINT "pressed dmin on your cassette
player. "
230 PRINT = PRINT ^PRIhfT "F-FlESS RETURN TO
START. "^hFUT RESPOhiSE*
250 POKE 54018. 52^ REM STARTS TAPE
300 GOSUB QUESTI0NASKJIME=I274:G0SUE: CL
OCK^GOSiJB QUESTIilWNSl'ER
310 GOSUB QUESTirjNASKTIME=b8^G0SLe CLO
152
Peripheral Information
CK^GOSUB QUESTIONhNSI'FR
320 GOSIB QUESTIQNHSK^TIME=b83M:B3Ue CLO
CK ■■ GOSLB QUEST I ONANSICR
330 GOSIJB i3UESTIOHA.Sh-MIf€-800^Gn::JJB CLO
CK^GOSUB i3UE£TI»¥iNSl€R
340 QOSUB QUESTI0m:5K::TinE=t'53^Gffi;UB Cijj
CK^GOSUB QUESTICWhHSICR
400 GRAPHICS 1 ^ SETDXiDR: 2.0. 14 SETCOLOR
4.0. 14 ^POSITION y;8 = PRIHT #6.;" EfCi OF
DEMO "ail1E=392: GOSIJB CLOCK
410 POKE 54018.. 60 ^REn 'SHUT OFF CASSETTE
500 GRAPHIi:^ O^END
2999 REM AheERIh^G SLEFijLlTI.NE
3000 PiJKE 5401 8. 60^ REM SHUTS OFF ChSSETT
E
3010 PRINT : PRINT "YOUR ftWEWER IS r^-U-P
LIT RESPOND*
3020 IF RESPONSEI=Hfe£RI THEN PRINT CHR;
$<253):PRIhfr ^F-RINT "COFlRECT ! " MjJTO 3108
;^0 PRIhTT : PR I NT "NO.. Tf€ hNSI.£R IS ".A
3100 PRIhfT -PRIINT "PRESS RETURN TO CONTI
MJE,. ."^hPUT RESPiDNSE*
3110 POKE 54018, 52^ REM TURN CASSETTE BftC
K ON
3120 RET^IRN
3999 REM QUESTION SIBR'OUTINE
4000 GRAPHICS 0:READ MIIEER.. COLOR, LINES..
ANSWER*
4010 SETCCLOR 2,C0L0R:,4:FPINT F-RINT ^PR:
INT "QUESTION #"; NUMBER^ PRINT ^PR'Ifrr
4020 FOR Cai^fT=l TO LIh£S^READ LINEI-PRI
MT LINE*:hE<T COJNT
4030 RETURN
4999 REM TIMIH: LOOP
5000 POKE 19>e:Fm'E 20.. 0^ REM SETS aOCK
TO
5010 IF PEEK(19>:^256+PEEK(20XTIME THEN
5010
153
Peripheral Information
5020 RETURh^
6000 DATA 1..5.3,CL0AD..H-,at iS the usual
BASIC coflifnand to ; tell tV& coiYiPuter to lo
ad a prosrant.-from cassette tape':^'
6010 DATA 2.10.2.LIST.l-Mt co.Miand wil]
sk)w you tJ->e pro-jsrarii stored in the cofvi
puter memory?
6020 DATA 3. 1.2.RU^..H'.at command execute
5 a prosram in. the computer's memory?
6030 DATA 4.3..3..CSAUE.lJ',at is the most c
offlfflonly-used HTARI,.B^SIC command i.eed to
record prosrams.to cassette tape:^
6040 DATA 5. 14.2.f€N..l-^at commarid wipes
out the prowam. ir\ memc-ry?
154
Peripheral Information
The Atari Disk
Operating System
Roger Beseke
A thorough examination of the disk operating modes.
Now that you have your ATARI 810 disk system up and running
and have undoubtedly saved and entered numerous programs and
data, you are probably wondering what else this machine can do.
Well, to date Atari has not released their DOS system manual, but
there is a preliminary manual which is available and contains a
wealth of information. The purpose of this article is to bring intci
the light some of the features hidden away in the preliminary
manual.
As we all know, after having the disk up and running, there is
a disk system menu which is displayed upon entry of the command
"DOS, RETURN". Some of these commands are straightforward
and rec]uire little or no explanation, but we are going to take a look
at all of them.
There are two neat characters we must discuss before we go
into the DOS menu of commands. They arc the asterisk (*) and the
question mark (?). When these characters are used in a DOS
command, they are referred to as wild carding. They allow excellent
flexibility which can be used to great benefit or dismay depending
what the operator is using the wild card character for. It probably
goes without saying that these characters should not be used in a
file label.
In the ATARI DOS, the (*) is used to free form a file name for
most of the commands. The asterisk can follow a portion of a label
in either the main file label or the extension. Note: The file name
does not have to be eight characters to use the extension. The
asterisk can be used in numerous ways to provide as many results. I
will cover a few here and leave the rest to your imagination. By the
way, all the commands in this article are in c]uotes. If the command
requires quotes, there will be double quotation marks. Also when
return is spelled out in caps, it means the "RETURN" key is to be
pressed.
A command of the form "*.*" will display all files on the
screen if used with the disk directory command (A). A command of
155
Peripheral Information
the form 'PROG*.*" would list all programs that met the first four
character format. Similarly the command "*.U*" would only list
files that had an extension in either the main or extension field, all
characters following it are ignored.
The (?) in the ATARI DOS is used to set a character to a do
not care condition when wild carding is used. The following
example, "WORD?S.*", shows that all files having the form
"WORD" and any other character in the don't care character field
will be operated on. These wild card characters can be used
anyplace in a legal label field.
Disk directory (A): The disk directory takes care of finding
and listing the files of a diskette. The files may be listed on the
screen or on your ATARI 820 printer. It is common knowlege that,
to get a display of the files on a particular disk, you must issue the
command "A RETURN RETURN" and they are displayed on the
monitor. This is fine if you do not have many files or if you want to
see all the files there are on the disk. If you do not want to see them
all, there are commands that can be sent to select a certain group of
files. They also can be printed on the printer. To get hard copy,
issue a command of ",P:" before the second "RETURN". A
command of the form "RA*.B?,P:RETURN" will list all files with
the first two characters "RA" in the main field and characters in the
extension which begin with a "B" followed by one character.
Run cartridge (B). This command exits the DOS and executes
in the left cartridge if one is inserted. It will not exit the DOS if a
cartridge is not inserted in the left slot.
Copy (C). The copy command enables the operator to copy a
file from one device to the disk or copy a file from one disk to
another file on another disk. For instance, a command of the form
"Dl:FILE,D2:PROG" will copy a file named "FILE" from disk one
to a file named "PROG" on disk two. You can write a file from the
screen editor to a disk file by a command similar to one of the form
"E:,NAME". This command must be terminated with a "CTRL 3"
key entry.
Delete (D). The delete command docs allow wild card
commands and can take the form of any of the previous examples.
The DOS displays a cue to the operator to delete the file shown.
The operator makes the appropriate entry and the DOS brings up
another file if there are wild cards used and files that meet the wild
card form. A typical deletion of all files with an extension of Bl thru
B34 could be deleted one at a time with the command
"*.B??RETURN". If "/N" is appended to the command, it will
156
Peripheral Information
delete the appropriate files without a cue, so be careful. It must be
remembered that locked files cannot be deleted.
Rename (E). The rename command allows you to change the
name of a file to another, and wild cards are allowed. A typical
command would be "FILE.KEEPFILE RETURN". This command
will change the name of the present file "FILE" to "KEEPFILE." It
must be noted that extreme care is recommended with this
command when using wild cards because you can end up with a
group of files with the same name.
Lock (F). The lock command as mentioned previously keeps
you from inadvertently writing to or deleting those files. A locked
file can be recognized readily in the disk directory mode because of
the asterisk ahead of the file name. Wild cards are also allowed in
this command. A typical command to lock all files would be
"*.*RETURN".
Unlock (G). The unlock command is the reverse of the
previous lock command and the same protocol is allowed. But
again, a word of caution using wild cards: you may be unlocking
something you do not want to.
Write "DOS" File (H). This command writes the DOS on a
formatted disk so that it can be booted into the computer at turn
on. This command allows you to make all your disks boot-loadable
and gives you a backup for the DOS.
Format Disk (I). This command is required for all new disks
before they can be written on. The DOS cues the operator as to
which disk to format. Again a double check is made to make sure
that is the disk the operator wants formatted because, if the wrong
one is formatted, all files are lost on that disk.
Duplicate Disk (J). The duplicate disk command allows you to
make a copy of your present disk on another even if you do not
have two drives to copy with. A typical entry might be
"1,2RETURN" where 1 is the source disk and 2 is the destination
disk. If you do not have two drives, the DOS will issue commands
on which disk to insert for writing or reading. Programs in memory
are destroyed when using this command and the DOS reminds you
of that fact when this command is entered.
Binary Save (K). Binary save is the command that one can
use to save all those machine code programs you generate if you
have an assembler. The binary save, unlike most of the other
commands utilized by the ATARI, uses hex numbers as opposed to
decimal. I suppose if you want to save those machine code
programs, you can count to sixteen using letters anyway. A typical
157
Peripheral Information
save binary program appears like "D2:N4ACHINE.CDE,4FEO,
6BAC RETURN". This would write a file called "MACHINE.CDE"
on disk 2. The data would be sax'ed from addresses 4FEO to 6BAC
inclusi\e. This command also allows the append syntax by placing it
immediatelv following the file name. An example is as follows:
"D:OPCODE/A,54E2,2BC3".
Now I am going to gi\e you a clue as to hciw to automatically
execute your program from a binary loacl command. Before you
become tocT elateci, there are some pains with all neat things, even in
the world of ATARI. You ha\'e to poke addresses 736 and 737 with
the starting address ot your binary program. Address 736 is the low
order byte of the starting address and 737 is the high order byte.
For you machine code users, the addresses are 02E0 and 02E1. Now
just append this to your program and away you go.
Binary Load (L). This is the command you use to load the
pre\iously saxxd binarv prc-)gram. There really is not too much to
say about it, especially if you append the starting address of your
program. You just enter the file name and let the system do the rest.
Run at Address (M). Run at address is for those of us who did
not ha\'e the hook ot how to do it. The DOS asks you run from
what address and you enter the address in hex, of course. After all,
we are binary programmers, are we not?
Define Device (N). The preliminary manual does not
recommend using this command as it is not perfected. Rumor has it
that there will be a re\'ision out soon to fix it, however. To me, that
is a challenge to find out what about it works and if it is useful. The
intent was to essentially change the name of a device and create
pseudo files and names. One example is 'T;FILE" where, whenever
"P" is referenced, it will write to a file "FILE" of whatever target you
directed it.
Duplicate File (O). Duplicate file is like the J command of
duplicating the disk except you do not duplicate as much: to be
exact, a file at a time. Again, if you only have one drive like some of
us, you can do it the same way as the duplicate disk command.
This has been a very brief description of what you can do with
the DOS and how it can work for you. I am sure that when the
DOS operator's manual comes out, it will explain everything much
better, but until then, maybe this will keep some of you file
manipulators out there happy.
158
Peripheral Information
Review of the Atari 810
Disk System
Ron Jeffries and Glenn Fisher
The Atari 810 disk system is very easy to install: unpack it, read a
couple of pages of the Operator's Manual, plug in two cords, turn it
on, insert a diskette, and you are up and running. (If, and only if,
you have 16K or more memory. Otherwise, the screen does strange
things, including producing some fascinating patterns.)
The Disk Drive Operator's Manual shipped with the early
units is actually only an 1 1 page looseleaf booklet. The information
in the booklet is clear, with an excellent diagram that should make
it possible for ahnost anyone to set up the disk system correctly.
Maybe that seems minor, liut things haven't aKvays been this way,
folks. On the other hand, 1 1 pages is not enough to say all the
things that need to be said to a person that just bought their first
disk. We didn't have any real problems, but then again the Atari
isn't the first disk we'\'e used. As of late January, the Disk Operating
System (DOS) Reference Manual isn't yet available. Atari has done
a great job getting a "total system" out, including disk and printer.
But documentation seems to be much harder to get out the door
than either hardware or software.
The disk drives are nicely packaged in injection-molded plastic
cases. You can stack two disk drives, and even put the 820 printer
on top and still have a stable arrangement that takes only a 10 inch
by 14 inch area. There are small indentations on the top of each
disk cabinet that provide a solid platform for the one stacked on top
of it. Everyone who has seen our unit has commented on how
attractive the packaging is, and how it looks like a consumer
product. One fact of life with the Atari is that there are lots of
cords to connect everything together, as well as to supply power.
Since Atari uses separate UL-approved power adaptors for
everything except the cassette recorder and the 820 printer, you
soon find that there are a lot of power adaptors to put somewhere.
On the other hand, having the transformers separate from the disks
and the computer probably ctintributes to their compact look.
To load the DOS, the 810 disk is turned on and the Master
Diskette (containing the DOS) is inserted. The Atari computer itself
is then turned on, which automatically drags the DOS into
159
Peripheral Information
memory. After about ten seconds, the message "READY" appears
on the screen. Now, when you type the command "DOS", a menu
will appear:
DISK OPERATIKG SYSTEM Q/24/79
COPYRIGHT 1^7^) ATARI
A. DISK DIRECTORY
B. RUN CARTRIDGE
C. COPY FILE
D. DELETE FILE
E. RENAME FILE
F. LOCK FILE
G. UNLOCK FILE
H. WRITE DOS FILE
I. FORMAT DISK
J. DUPLICATE DISK
K. BINARY SAVE
L. BINARY LOAD
M. RUN AT ADDRESS
N. DEFINE DEVICE
O. DUPLICATE FILE
SELECT ITEM
"Run Cartridge" means "leave DOS." At least for now, the DOS
can't be used unless you are using the BASIC cartridge. Later on
there may be other languages. One that we hcipe to sec soon is an
assembler and editor for working with 6502 machine language.
A good feature of the Atari DOS is the ability to "lock" a file,
so that it can't be deleted, renamed, or written into. This can be
very handy if you have an important file that you want to protect.
(As an aside, we've heard that the same people that wrote the Apple
DOS worked on the Atari version. Guess what? Apple is the only
other micro system we know of that has a "lock" capability.)
"Write DOS" is how you make new copies of the DOS. Unlike
some systems, the Atari DOS is a normal file, instead of being
hidden away in some secret location on the disk. Each diskette can
hold 709 sectors of 128 bytes each. The DOS takes 64 of these
sectors, leaving 645 sectors, or about 86K bytes, for your files.
Alas, all is not sweetness and light.
First, the DOS uses about QK of your memory. So, on a 16K Atari,
when you first turn on the system you'll have about 4300 bytes left
of the 16K. (Here is the math; a "pristine" 16K Atari has 13326
bytes of memory available for your program. The rest is used by
BASIC, the operating system, and as screen memory. The Atari
DOS comes configured for tour drives, and when it is loaded into
160
Peripheral Information
the computer you have 4328 bytes left. If you change a couple of
parameters to tell the system you only have one drive you can free
enough memory to have a total of 4622 bytes available.)
There is a short BASIC program that you can run which
throws away most of the DOS, leaving only the ability to Load from
and Save to the disk, as well as access the disk from BASIC
programs. Howver, when you do this, you can't even look at the
directory ofthe disk without running a special program, nor is it
possible to save this small DOS so that you can "boot" from it,
since the ability to write a DOS file went away when you threw out
the menu. So, if you want to use "Tiny DOS," each time you boot
the system you'll have to run the BASIC program. In this "strippeci
down" mode you have about 9.4K available.
What can we say? Well, although the menu seemed friendly
and handy at first, when you consider what it costs in memory, it
may not be worth it. A more important issue is which DOS
functions are crucial, and which can be shunted off into a separate
"disk utility." Given the tight memory situation, we'd vote for the
following as essential DOS functions, with everything else exiled to
Siberia: directory, delete file, and, of course, load and save files.
These important DOS functions would ideally be direct commands,
such as "DIR" or "CATALOG" for the directory.
Atari file names can only be UPPER CASE letters and digits.
Why they chose such a restricted set is a mystery, since only
comma, period, colon, asterisk and the ciuestion mark have special
meaning to the DOS. File names consist of eight characters followed
by a three-character "extension." Eight-character names arc too
short to be really meaningful. (Just because CP/M and DEC made
that mistake doesn't mean it should be repeated. Commodore
allows 16 character names, and they can contain almost any
characters you like.) Speaking of UPPER CASE, the 800 itself has a
"feature" we find frustrating: it doesn't understand lower-case
BASIC keywords!
To summarize, we find many things about the system that we
like, as well as some things that aren't what they could ha\'c been
with a little better planning and design. Atari has put tcigether a
good system, one that we think will sell like gangbusters. It's
available now, at obscure places like Scars and J.C. Penneys and the
like, as well as your friendly local computer store.
161
Peripheral Information
An Atari Tutorial:
Atari Disk Menu
Len Lindsay
This program permits greater efficiency when using disks.
Anyone with an ATARI disk will really appreciate this program.
You will probably put a copy of MENU on each of your diskettes.
MENU will display the programs on the diskette along with an
ID number (1-44). It then asks you which program you wish to
RUN. If you wish to RUN program number 8, you simply answer 8.
It then LOADS and RUNs that program. No more hassles trying to
remember exactly what name you used for the program, or typing
the name exactly. MENU does it all for you.
Since MENU uses some special techniques, I will explain how
it works. You should be able to apply many of these concepts to
your own programs.
LINE 10-11 - Dimension the STRINGs. ARRAY$ will hold all
the names of the programs on the disk (12 characters per name).
FILE$ and NAME$ are used for the program names. DISK$ is used
to hold the drive number prefix.
LINE 15 — Set the margins to default, in case the previous
program used differed ones.
LINE 20 - Use GRAPHICS full screen text mode. It also clears
the screen for you.
LINE 30 — Turn the cursor off — it looks nicer while writing the
program names on the screen.
LINE 40 — Set the color registers to the preferred colors. A light
orange backgroimd with warm brown letters is the easiest on your
eyes.
LINE 50 — Set DISK$ to the disk drive to be used. See
modification notes to make this more flexible.
LINE 60-70 — "Dl:*.*" will refer to the disk directory. It is a two
step process to add the DISK$ with "*.*" and call it NAME$.
LINE 100 — Open the disk directory for a READ. This line should
be useful for other applications.
LINE 110 — Initialize the counter which counts each program as it
162
Peripheral Information
is read from the directory. This also acts as the program ID number.
LINE 120 — READ one file from the directory. A program entry is
17 characters long. It is two spaces, 8 characters for name, 3
characters for extension, one space, 3 characters for sectors used.
After all the programs, there is a separate record of the number of
free sectors left on the diskette.
LINE 130 — Check if this is the short record of tracks left on
diskette. If it is, then we are done and should go on to the next part
starting at line 500.
LINE 140 — Since we read in another program name, add one to
the counter.
LINE 150 — If this is the 23rd program, we must switch to the
right half of the screen (prevent scrolling and fit more on the screen
this way). To do this we set the margin to 20 and position the cursor
at the top line, 20th spot.
LINE 160 — Check if the screen is completely filled with program
names (44 is the maximum display allowed on one screen). If it is
full, ignore all the rest, adjust the counter accordingly. See
modification notes for other ideas.
LINE 200 — Initialize the name field. To manipulate the string by
character position, the positions all must exist. Initializing to " "
(null) will not work. Note the extention dot is in position 9.
LINE 210 — If there is no extension, get rid of the dot in position 9.
LINE 220 — Assign the program name from FILE$ which we just
READ from the diskette. This is only the first 8 characters of the
name, not including the extension.
LINE 230 — Assign the extension of the program name. If there is
no extension, we still can assign it since the dot has already been
removed.
LINE 300 — To keep a justified column of ID numbers, we must
allow for one digit numbers. So if the number is less than 10, print
an extra space.
LINE 310 — Print the ID number followed by ) and a space.
LINE 320 — Print the program name.
LINE 400 — Add the name onto the ARRAY$ we are building. It
can now be referenced by number times 12 (since every name is
exactly 12 characters long).
LINE 410 — Processing complete for the program just read. Go
and do the next one.
163
Peripheral Information
LINE 500 — Set the trap to come back and redo the input if an
error occurs.
LINE 505 — CLOSE the file used to input the programs from the
directory.
LINE 510 — Turn the cursor back on for the INPUT request.
LINE 520 — Position the cursor on the message line (line 22). First
print a line-delete to erase the previous message. Then print the
current message. End the message with a BEEP (control 2).
LINE 525 — Set the left margin back to default so the next
program will not be affected.
LINE 530 - INPUT the ID number of the program to be RUN.
LINE 540 — Get rid of any fractions.
LINE 550 — If the choice was not in the range available, go and
ask again.
LINE 600 — Start FILE$ with the disk number. The rest of the
name is assigned in line 630.
LINE 610 — Assign the name of the program chosen to NAME$
(taken from the ARRAY$ we just put together).
LINE 620 — Start a loop to go through the whole 12 character
program name and remove all spaces (spaces cannot be imbedded
within a program name when you ask for a LOAD or RUN).
LINE 630 — Add the characters in the program name one at a
time to FILE$. Ignore spaces.
LINE 640 — Do the next character.
LINE 700 — Set the trap to line 900 to print a can't load message if
there is a disk error.
LINE 720 — Position the cursor to the message line. First do a line
delete to erase the previous message. Then print the message
LOADING with the file name. Then print a BEEP (control 2).
LINE 730 — RUN the program and spring the trap.
LINE 900 — Print message the program can't be run (maybe
diskette was switched or removed since the directory was read).
LINE 910 — Pause to allow message to be read.
LINE 920 — Go and ask for program to RUN again.
Possible Modifications
MENU is set up to work with disk drive 1. It is easy to have it work
with both drive 1 and drive 2, and even alternate between them for
164
Peripheral Information
a wider MENU choice. Line 50 sets the disk drive number prefix to
be used by the MENU program. Some possible modifications follow;
the first asks you which drive to use for the MENU, while the
second can flip back and forth from drive to drive. I have
implemented the second set of modifications and find it works quite
well. Either way, it seems that it doesn't like trying to give you a
MENU for an empty drive.
Modification Set 1 — Ask Which Drive
50 PRINT "[CLEAR] WHAT DISK DRIVE TO USE)";
51 OPEN #1, 4, 0, "K:" :REM OPEN KEYBOARD FOR
GET
52 TRAP 52: GET #1, DRIVE : REM GET KEY PRESSED ATASCII VALUE
53 NAME$ = CHR$(DRIVE) : REM CONVERT TO STRING - USE
NAME$ SINCE IT IS DIMed
54 IF NAME$<"1" OR NAME$> "4" THEN 52 : REM TRY AGAIN
55 PRINT NAME$ : REM PRINT THE REPLY
56 CLOSE #1 : REM CLOSE THE FILE
57 DISKS$ = "Dl:" : REM INITIALIZE STRING
58 DISK$(2,2) = NAME$ : REM INSERT DRIVE NUMBER
Modifications For Alternating Drives
17 DRIVE = 2 : REM INITIALIZE FOR A TWO DRIVE SYSTEM -
DRIVE 1 WILL BE FIRST
18 DISK$ = "Dl:" : REM INITIALIZE
50 DRIVE = 3-DRIVE : REM SWITCH DRIVES, WILL DO DRIVE 1 FIRST
55 DISK$ (2,2) = STR$ (DRIVE) : REM PUT CORRECT DRIVE NUMBER
INTO DISK$
59 TRAP 50 : REM TRAP DISK ERROR
105 ARRAY$ = " " : REM INITIALIZE
115 PRINT "[CLEAR]';- : REM CLEAR SCREEN
520 POKE 82, 2 : REM LEFT MARGIN TO DEFAULT
525 POSITION 2,22 : PRINT "[DELETE LINE]0=NEXT DRIVE WHICH
TO RUN[CONTROL 2]";
535 IF CHOICE = THEN 50 : REM SWITCH DRIVES ON CHOICE OF
Another modification you may wish to make has to do with the
ability to jump into DOS immediately directly from MENU. If you
try to RUN it as your MENU choice, it will say "can't run dos."
Thus, if you think you may need to jump directly to DOS add this
line:
615 IFNAME$ = "DOS .SYS" THEN DOS
Modifications To Overcome The 44 Program Limit
The MENU can only display 44 program choices at one time, thus
line 160 checks if the screen is full(44). If it is, it skips all the rest of
the programs. In practice this should not be a problem since most
diskettes will be filled before they reach the 45th program unless the
programs are all short.
165
Peripheral Information
Modifications might be made so that after 44 programs, they
no longer are printed on the screen, but still are added to ARRAY$
with FILECOUNT continuing its count. The DIM in line 10 for
ARRAY$ should be increased accordingly. The message line
(520-525) should also be appropriately changed. Perhaps a choice of
99 would mean "display second screen of menu." A subroutine
could calculate what program number to start with (filecount minus
43) and another subroutine could print the menu from ARRAY$ as
appropriate.
RB1 U^- reilJ (44 PROGRAM MAX)
1 REM ZU a') 1S€U LEM LIhCSAY
2 REM tU Lft3T FB-'ISION 11-15-30
3 REM
18 DIM ARRHY*':52S>.FILE^<2M).,MHnE*(28)
11 DIM DISK:f'.;3:.
15 POKE ;E:2..2FiiKE 83. 39^ REM DEFAULT MhRG
IHS
20 GRAPHICS y^REM CLEAR KREEM AND GO IN
TO TEXT MODE G
30 POKE 752.. 1- REM CURSOR OFF
40 SETCOLOR 2.2.^6^ SETCOLOR 4.2..b:SETC0L0
R 1..2..2
50 DISKf="Dl:"^REM THE DISK TO BE USED F
OR H ME.NLi
60 lttMEf=DISKf REM THE rlAfE MUST START W
ITH THE DISK DFTIE HUM3ER
70 HAMEf ^ LENx m^$ >^ 1 )="t , * " ■ REM LOffi I hC
DVZ.t GIUES THE DISKS DIRECTORY
lOOjIiFtN #l..b.:0..NAMEf :REM CfEM THE DISK
DIRECTORY FOR A READ
lie FILECjiliT-:OREM INITIALIZE COUHT
128 IMPUT #:.,FILE$^REM READ hEXT PROGRAfl
hJAME
130 IF L£N(FILEJ)^5 THEM 500 ^ REM HOT A P
ROGRAM - THIS IS THE SECTORS LEFT COUHT
140 FILFCOLiNT^FILECOUNT-ri^REM ADO OfE TO
iJOliNT
150 IF FIlECUUNT=23 THEM POfCE S2.20E'OSI
TIOH 2a.. 0- REM Sl^nTCh TC RIGHT HALF OF SO
REEN -CHAHGE LEFT MARGIN TOO:.-
160 IF FILESOIJHT>44 THEN FILEC0LiNT=44 ■ GO
166
Peripheral Information
TO 126^ REM T'OO :lHriY PROGRAMS - JUST KEEP
RtADIHG
2m imE$-" "^REf1 INITIALIZE
THE h«1E FIELD TO ALL BLArlKS EXCEPT THE
DOT BEFORE THE EXTErCION
210 IF FILE$ai>13>=^' " THEN NArOO.?
)=" "^REr-^ THERE IS HO E^aENSIOH SO GET R
ID OF THE DOT
220 \mE$': 1 .. S )=F I l£p: 3 .. 1 ) ■ REM ASS I Ql TH
E FIRST S CHARhCTERS OF THE PROGRAM hJAME
230 NAME$':i0.. 12;=FILE$(11..13)^REM ASSIGN
THE EXTEMSIOri OF THE PROGRAM MhME
300 IF FILEOnUrr:i0 THEM PRINT " ".;^REM
ADD AN EXTRh SPAOE SEFCRE THE SINGLE DIG
IT HONBERS TO hlIGM wITFi 2 DIGITS
316 PRINT FILEOOJhTr') ".; ^REM PRINT FILE
MJMBER
320 PRINT NAfttiTREM PRIriT THE PRGGRAN NA
m
490 HRR.:YiF(LEH(HRRftY:f>»-l)=^JAnE:rREM ADD
ON THE LA^ES^ NAME TO Er© OF STRING OF \i
AMEG THLiS FhF:
410 GOTO 120 REM GO READ r£;;T FILE NAME
500 TRhP 560 rem SET TRAP FOR BAD IfjRUT
505 CLOSE #rREM CLOSE THE FILE USED TO
INPUT DISK DIRECTORY
510 POKE 752.0 REM TURN CUF:SOR BACK Hi
520 PCS n Or. 2.22 PRINT " RUN NUMBERJ".;^
REM PRINT MESShGE ON MESShGE LINE
525 POKE 02. 2 -REM SET LEFT mRGIN TO DEF
AULT
530 INPUT CHOICE REM GET THE NUMBER OF T
HE PROGRAM TO RUN
540 OHO I CE= I NT..: choice:: -REM GET RID OF PR
ACTIOhE
550 IF CHOICE-:! OR OH0ICE>FILEC0UNT THEN
500 REM OUT OR RANGE FOR THIS MENU
600 FILEI=DISKJ:P£M THE NAME TO USE WITH
A RUN STATEMENT MUST BEGIN WITH THE DIS
K DRIUE NUMBER
b 1 NAME:? =^ARRh'v $< CHO I CEY 12-11 .. CHO I CEY 1 2 )
167
Peripheral Information
:REM THE NhTIE QF THE PROGRhM IHCLUOIMG E
XTRh SPACtS
b2i3 FOR L0QF~1 TO 12
639 IF HrtriEi?a.riuP..LuOP><>" " THEN FILE$(
IBK FILEI )+l )=NHriE$( LOOP.. LCCP )
64y \£yj LOOP
700 TRAP 900 REr! SET TRAP FOR DISK ERROR
720 PO^JTIOfJ 10. 22^ PRINT " LOADING }".HA
rE:f ■■ F:Ef1 PRIhJT r-ESSAGE ON rCS-SAGE Ll\£
730 RUN FILEJ^TRAP 345b7:F£ri RUN THE PRtD
GRAM AND TlJRhi' OFF TRAF'
900 POSITim 10..22T'RINT " CAN'T RUN }".;
HAMEI-REM FRIf^T fESSAGE ON MESSAGE LlrE
910 FOR PhUSE=1 TO 999^MEyT PAUSE ^ REM DE
LAY TO ALLOW TirE TO READ MESSAGE
920 GOTO 5m0:F'EM GO AND TRY AGAIN
168
Peripheral Information
What To Do If You Don't
Have Joysticks
Steven Schulman
Use of joysticks with the ATARI computer can add excitement to
your programs. But what do you dci if you don't have joysticks yet
and aren't ready to buy them? Arc you out of luck? Do you have to
type in numbers to select from a menu of answers? Does it mean you
can't use games like IRIDIS' ZAP or the latest from your ct:)mputing
magazines? No! There's another way.
We can look in amongst the bits and bytes that make up the
memory of your ATARL Any time yc:iu press a key on your
keyboard, the value of the 764th word changes. By taking a PEEK
at what number is there ytui can find out which key it was. Listing I
shows you how to find out what the value will be when any key is
pressed. Try running it and pressing different keys, shifted and
unshifted, reverse video, etc. When you finish, use the BREAK key
to stop the program.
"How does this help solve my problem of not having
joysticks?" you may ask. To see this you have to know what
happens when you use the joysticks. If your program has a line I =
STICK(l), the value of I will be one of 9 possible values depending
on the position of the joystick when that line is reached. The values
will be
where the value of I = 15 means that the joystick is in the upright
position. In addition, J = STRIG(l) will have a value J = if the
fire button is pressed and a value of J = 1 if the fire button is not
pressed.
Returning to what we know about the value of the last key
169
Peripheral Information
pressed, we found that the \'nkies for the arrows were:
[up-arrow] = 14
[down-arrow] = 15
[right-arrow] = 7
[left-arrow] = 6
and the \-alucs for the shifted arrows were
Shift = 78 Shift = 71
Shift = 79 Shift = 70
Fuially, tlie \-alue for tlie space bar is 33.
\X'e can therefore ha\'e the same results as we would get from
using a jovstick by using the arrows, shift arrows and space bar. The
space bar will be our firing button, the arrows will be the obvious
up, down, left and right, and the shift up will be to the upper left,
the shift down will be to the upper right, the shift left will be to the
lower left, and the shift right will be to the lower right. Any other
kcv, or no key at all, being pressed is equal to the joysticks being in
an upright position.
The routine in listing II will play the part of a joystick. After
calling the subroutine the value of I will be the same as would ha\'e
been returned by I = STICK(l) and the \alue of J will be the same
as what would ha\'e been returned by J = STRIG(l). When you do
buv your joysticks, simplv replace the subrcTutine call and remove
the subroutine from your program. Happy computing!
Listing I
118 ? "I=M:REri PRIWT 1\£ UALUE Cf THE
¥£i PRESSED
120 POKE 764. 255 = RBI TELL T>£ COMF'UTER T
HAT NO KEY 1>IAS PRESSED
130 FOR PAUSE=1 TO SSe^hOT F-ftUSE-REM SL
OW Down THE MACHIHE SO YOU CrtH READ THE
RESIXTS
140 GOTO 100
Listing II
100 JOYSTICK=1080 = REn LOCATION OF SUBFOJ
TU€
110 GOSUB .JDYSTICK^REM i>€C:K THE 'JOt'STI
CK'
170
Peripheral Information
120 ? "THE '..m'STICK' Hfti liALUE=";I
130 ? "THE 'FIRE EiUTTCW HAS UALLE=";.J
140 FOR PAU5E=1 TO 500 = h£XT F-fllSE
150 rjilO 118
1908 REM .jaySTICK SUBROUTINE
1010 I=PEEK:(7b4)
1020 .J=l
1030 FtlKE 764/255
1040 IF 1=14 THEN I=14:F£TIJRH
1050 IF 1=79 THEN I=€-F£TIJRN
1060 IF 1=7 im\ I=7--FfTURH
1070 IF 1=71 THEN 1=5 ^ RETURN
1080 IF 1=15 THEN I=13-F£TURN
1090 IF 1=70 im\ 1=9: RETURN
1100 IF 1=6 T^€N 1=11: RETURN
1110 IF 1=78 TF€N 1=18 ^ RETURN
1120 IF 1=33 T^£N 1=15 :.J=0: RETURN ^FSM F
IRE BUTTON
1130 I=15:RETLF*^
171
Peripheral Information
Using the Atari
Console Switches
James L. Brunn
If onh one key is pressed, you can use these values: (PEEK (53279)):7 =
no /<e>-, 6 = START, 5 = SELECT, and 3 = OPTION.
The colored console switches to the right of the typewriter keyboard
are just the ticket for programs with special features. The names
seem to indicate just the kind of things one might wish to do in a
program. OPTION — What better key to step through a choice of
options. SELECT — After stepping through the options, this key
could be used to select the current option. START — This key
might be used to transfer control back to the beginning of a
sequence or to start the program over again.
The problem is, how does one read these keys? Well, read on:
here is a method that works well for me. First, we note the memory
location 53279 is used to indicate the condition of all three switches.
It's done like this. If we just PEEK (53279) with no switches pressed,
we find a seven. Holding down one or more of the keys while doing
our PEEK returns a different number. The table below summarizes
the values returned when a console key is pressed. X means that the
key or keys are pressed.
Table 1
KEY VALUE
1
2
3
4
5
6
7
OPTION
X
X
X
X
SELECT
X
X
X
X
START
X
X
X
X
Nc
let's use this knowledge in a program.
10 DIM DISPLftY*(23)
20 PRIHT " {CLEAR} "= POKE 752,1
30 POSITION 5.5
40 KEYS=PEEI':X 53279)
50 OH KE^'S+l OKUB 106.. 110. 129, 138, 140,1
50,160.170
60 PRIHT DISPLAY*
70 GOTO 30
172
Peripheral Information
lee DISF'LAY*="iDPTION + :5ELECT + START
RETURN
118 DISPLAY-|="rjpTIW + SELECT
RETURN
120 DISPLAY-|="i3^TICW + START
RETURN
138 DISPLAY*="UPTI0H
RETURN
148 DISPLAY$=" SELECT + START
RETURN
150 DISPLAY$=" SELECT
RETURN
160 DISPLAY*=" START
RETURN
170 DISPLAY*='"MD KEYS ARE PFESSED
RETURN
Of course the subroutines here are very simple,
but this method can easily be expanded to fit
your needs.
173
Peripheral Information
Atari Meets The
Real World
Richard Kushner
You've had your Atari computer for a while, reached the level of
Commander in Star Raiders, killed 754 aliens in Space Invaders,
learned the difference between PUT and GET and written some
programs to amuse and astound your friends and family. Now
you're looking for new worlds to conquer. Lurking out there past
the peripheral plug on your Atari, and just beyond the end of your
telephone line, is the real world. To get there from here means
connecting your Atari to something that speaks the language of the
outside world. As often as not, that means using an RS'232
compatible device. All this really means is that many devices that
can hook onto your computer require a connection with voltage
and signal specifications given by the RS-232 technical standard.
Printers use it, modems use it, and a wide range of other peripherals
are most comfortable communicating across it.
So what do you do? You can build an RS'232 interface, but if
you're like me, your interest lies more at the programming end and
you'd prefer something that comes ready to go. Pm pleased to report
that such a device exists and works very well, thank you. It is the
Atari 850 Interface Module and it does a lot of things to make the
interfacing easy and understandable while, at the same time,
providing versatility and supporting future expansion. This article
will give a rundown of many of its useful features.
The Model 850 plugs into the Atari peripheral port and
provides connections to daisy chain other devices (like the tape
cassette) that do not require the interface. It has its own power
supply (identical to the power supply for the Atari computer) and
supports four RS'232 serial ports and one parallel port. The parallel
port is intended for the Atari 825 Printer (a slightly disguised
Centronics 737 Printer) and the manual describes the leads to all
the pins in case your parallel device is not Centronics compatible.
The four serial ports have different levels of support. Port #1 is
intended for modems. Ports #2 and #3 are intended for serial
printers and other generally receive-only devices, and Port #4
supports a 20ma current loop for teletype interfacing. The key word
here is RS'232 "compatible." The connections are nine pin as
174
Peripheral Information
opposed to the 25 pin on standard RS'232 connectors and therefore
cannot support all the possible RS-232 interconnections. Table 1
shows the connections that are available on the four ports. They
should be adequate for most personal computer hook-ups. You'll
have to make a connector to bridge the gap between the Model 850
and your RS-232 device. Carefully note that the pin designations
are relative to each device, i.e., "receive" on the Model 850 goes to
"send" on the peripheral and vice versa. Understanding that fact
makes the interconnection reasonable and straightforward.
So far we've just scratched the surface. Inside the Model 850
resides its very own microprocessor. When the system is powered
up, the Model 850 passes a handler routine and serial port
information up to the computer and then waits for instructions. To
transmit or receive over any port you must configure the port (or
accept the default configuration). You can specify baud rate (45.5 to
9600, concurrent (two way) or block (output only) communication,
port number, translation (how to send Atari ASCII so that your
ASCII only device won't hiccup), bits per word, parity, and whether
or not to monitor signals from the device at the other end. The
length of the list and the variety within each item should give an
indication of the versatility of this device. The cost to you (besides
the purchase price, of course) is the 1,762 bytes of memory used
when the interface loads its handler and tables into the computer
memory. The following is a brief description of some of the features:
1. Baud Rate: virtually all common baud rates from 45.5 (60
words per minute for Baudout teletypes) to 9600 baud are supported
and software-selectable. 300 Baud is the default value, making it
immediately compatible with modems. I currently have a 1200 Baud
serial printer running.
2. Translation Mocies; three modes can be used —
a.) no translation — just like it says, no changes are made
on sending or receiving characters. This is only useful if
you have some way of processing the characters or if
your peripheral device understands the Atari version of
ASCII, as, for example, if you are talking to another
Atari computer.
b.) light translation — on output End Of Line (EOL) is
translated into Carriage Return (CR) and vice versa on
input. Also the high bit is set to zero. This is the default
mode.
c.) heavy translation — this mode does what light
translation does plus, on input, it looks for
175
Peripheral Information
correspondence between Atari ASCII and regular
ASCII. If there is correspondence then it passes the
character on and, if not, it translates the character into
whatever you have specified as the "won't translate"
character. On output, however, untranslatable
characters are not sent at all.
4. I/O Modes: the interface handles either concurrent or block
output. Input must always be done in the concurrent mode. In the
block output mode, data is sent to the interface module in 32
character blocks, then the computer waits for the block to be
transmitted before sending the next block. It is possible to force the
computer to send a block of less than 32 characters so that data
need not be lost. Concurrent mode output sends characters to a 32
character buffer which continuously empties out the other end.
Programs are not held up in this operation unless the buffer fills up,
in which case the computer must wait until space becomes available.
There are other capabilities built into the interface, but it is my
intention here to give you a feel for the power of this device rather
than to give a recitation of the technical manual. Don't be afraid to
try to interface non-Atari RS'232 devices to your Atari. This
interface module should be able to support whatever you have,
although you'll probably have to experiment with the library of
commands to get communication to take place. For example, the
Atari directly supports the LPRINT command which outputs data
to a parallel printer on the appropriate connection of the interface
module. For my serial printer, it was necessary to 1) establish a port
for the device (calling OPENing a channel; 2) configure the port to
output data at the 1200 Baud rate that the printer required; and
3) look into whether or not I needed a line feed after a carriage
TABLE I
PORT -1
PORT -2
PORT -3
PORT -4
XMT
Transmit
XMT
XMT
XMT
RCV
Receive
RCV
RCV
RCV
DTK
Data Terminal Ready
DTR
DTR
DTR
DSR
Data Set Ready
DSR
DSR
RTS
Request to Send
RTS
CRX
Carrier Detect
CTS
Clear to Send
return. All of this really required only two statements near the
beginning of my program and the use of PRINT #4 (where 4 is the
device number I had set up) rather than LPRINT, when I wished to
176
Peripheral Information
send data to the printer.
The Model 850 Interface Module has been carefully thought
out to provide a great deal of versatility to the user. Several months
of experience with this device has convinced me that it is a good
investment in future expansion of my Atari computer system and a
worthwhile item to have now.
177
178
Appendix A
179
Atari
Memory Locations
Ronald Marcuse
DEC ADDR
HEX ADR
LABEL
000 1 4
OOOD
APPMHI
oi:ii:i 1 5
OOOE
APPMHI
00016
0010
POKMSK
000 IS
0012
RTCLOK
00019
0013
RTCLQK
i'iiJCi2C'
0014
RTCLDK
00065
Q041
SOUNDR
00077
004-D
ATTRMDD
000B2
00S2
LMARGIN
("xJOOo
00S3
RMARGIN
00084
0054
RDWCRS
OO0S5
0055
CDLCRS
0OOB6
0056
COLCRS
C>L)(J90
005A
OLDROW
CjOC)9 1
005B
DLDCOL
00092
OOSC
OLDCDL
00093
005D
DATCURS
0i:i096
OO&O
NENROW
00097
0061
NEWCOL
0009B
0062
NEWCOL
00106
006 A
RAMTOP
00 1 28
O080
LOMEM
00129
0081
LDMEM
Citjl 44
OO90
MEMTDP
00145
0O91
MEMTQP
00186
OOBA
STGPLN
00 1 87
OOBB
STOPLN
00 1 95
00C3
ERRSAV
0020 1
00C9
PTABW
002 1 2
O0D4
FRO
00213
00D5
FRO
0025 1
OOFB
RADFLG
00559
022F
BDinCTL
00560
0230
SDLSTL
0056 1
0251
SDLSTH
00562
©2,38
SSKCTL
00564
0234
LPENH
00565
0235
LPENV
00580
0244
SYSRES
00623
026F
GPR I OR
00624
0270
PADDLO
00625
0271
PADDLl
00626
0272
PADDL2
00627
0273
PADDL3
00628
0274
PADDL4
00629
0275
PADDL5
00630
0276
PADDL6
00631
0277
PADDL7
00632
0278
STICKO
00633
0279
STICKl
00634
027A
STICK2
00635
OZ?B.
STICK3
00644
feiB4:
STRIGO
DESCRIP
BASIC HIGHEST LDC- LBB
BASIC HIGHEST LDC- MSB
OS INTERUPT REQ ENABLE
TV FRAME CNTR- LSB
TV FRAME CNTR- NSB
TV FRAME CNTR- MSB
NOISY I/O FLAG (0=QUIET)
ATTRACT MODE FLAG, 128=YES
LEFT SCREEN MARGIN
RIGHT SCREEN MARGIN
CUR CURSOR ROW.QR WINDOW
CUR CURSOR COL, GR LSB
CUR CURSOR COL, GR MSB
PREV CURSOR ROW, GR WIND
PREV CURSOR COL, GR LSB
PREV CURSOR CGL.GR MSB
DATA UNDER CURS, SR/MD
CURSOR ROW FDR DRAWTO
CURSOR COL FOR DRAWTO LSB
CURSOR COL FOR DRAWTO MSB
TOP OF MEMORY, # OF PAGES
BASIC LOW MEMORY PNTR LSB
BASIC LOW MEMORY PNTR MSB
BASIC MEMORY TOP PNTR LSB
BASIC MEMORY TOP PNTR MSB
1st HALF STOP/TRAP LINE #
2nd HALF STOP/TRAP LINE #
ERROR NUMBER
PRINT TAB WIDTH (DEF 10)
LOW BYTE VAL,USR FUNC
HIGH BYTE VAL,USR FUNC
RAD/DEG FLAG 0-RAD,6-DEG
OS DIRECT MEM ACCESS CON
OS DISPLAY LIST PNTR LSB
OS DISPLAY LIST PNTR MSB
OS SERIAL PORT CONTROL
LIGHT PEN HORIZ VAL
LIGHT PEN VERTICAL VAL
SYS RESET, COLD START >0
PRIORITY SELECT (OS)
PADDLE O
PADDLE 1
PADDLE 2
PADDLE 3
PADDLE 4
PADDLE 5
PADDLE 6
PADDLE 7
JOYSTICK O
JOYSTICK 1
JOYSTICK 2
JOYSTICK 3
JOYSTICK TRIG
180
DEC ADDR
HEX fiDR
LABEL
DESCRIP
00645
0285
STRIGl
JOYSTICK TRIG 1
00646
0286
STRIB2
JOYSTICK TRIG 2
00647
0287
STRIG3
JOYSTICK TRIG 3
00656
0290
TXTROW
CURSOR ROW, TEXT WINDOW
00657
0291
TXTCOL
CURSOR COL, TEXT 1st HALF
0065B
0292
TXTCOL
CURSOR COL, TEXT 2nd HALF
00704
02C0
PCDLRO
OS PLAYER-MISSILE COLOR
00705
02C1
PCOLRl
OS PLAYER-MISSILE 1 COLOR
00706
02C2
PCDLR2
OS PLAYER-MISSILE 2 COLOR
00707
02C3
PCDLR3
OS PLAYER-MISSILE 3 COLOR
00708
02C4
COLDRO
COLOR REGISTER
00709
02C5
COLOR 1
COLOR REGISTER 1
0i:i7 1
02C6
C0LDR2
COLOR REGISTER 2
007 1 1
02C7
COLORS
COLOR REGISTER 3
007 I 2
02C8
CDL0R4
COLOR REGISTER 4
0074 1
02E5
MEMTOP
OS MEMORY TOP POINTER LSB
00742
02E6
MEMTOF-
OS MEMORY TOP POINTER MSB
00743
02E7
HEMLO
OS LOW MEMORY POINTER LSB
00744
02EB
MEMLG
OS LOW MEMORY POINTER MSB
00752
02F0
CRSINH
CURSOR INHIBIT 0-ON,1-OFF
00755
02F3
CHACT
CHAR REG 1-BL, 2-NOR, 4- ■■
00756
02F4
CHBAS
CHAR BASE 224-UP, 226-1 ow
00763
02FB
ATACHR
LAST ATASCII CHAR
00764
02FC
CH
LAST KEY HIT, 255 CLEARS
00765
02FD
FILDAT
GR. FILL DATA (XIO)
00766
02FE
DSPFLG
DISPLAY FLAG 1=DIS CON CH
00767
02FF
SSFLAG
START/STOP PAGING (CON/1)
00794
03 1 A
HATABS
HANDLER ADDR TBL,3 BY/HND
00B32
0340
lOCB
in CON BLOCKS, 16 BYT/IOCB
53248
DOOO
HPOSPO
HDRIZ PDS, PLAYER
53248
DO(")i't
MOPF
MIS - PLAYFIELD COLL IS
53249
DOOl
HPOSPl
HORIZ POS, PLAYER 1
53249
DOOl
MIPF
MIS 1 - PLAYFIELD COLLI S
53250
D002
HP0SP2
HORIZ POS, PLAYER 2
53250
D002
M2PF
MIS 2 - PLAYFIELD COLL IS
53251
D003
HP0SP3
HORIZ POS, PLAYER 3
53251
D003
M3PF
MIS 3 - PLAYFIELD COLLIS
53252
D004
HPOSMO
HORIZ POS, MISSILE
53252
D004
POPF
PLAY - PLAYFIELD COLLIS
53253
D005
HPOBMl
HORIZ POS, MISSILE 1
53253
D005
PIPF
PLAY 1 - PLAYFIELD COLLIS
53254
D006
HP0SM2
HORIZ POS, MISSILE 2
53254
D006
P2PF
PLAY 2 - PLAYFIELD COLLIS
53255
D007
HP0SM3
HORIZ PDS, MISSILE 3
53255
DO 07
P3PF
PLAY 3 - PLAYFIELD COLLIS
53256
D008
MOPL
MIS - PLAYER COLLISION
53256
DOOB
SI ZERO
SIZE- PLAYER
53257
D009
MIPL
MIS 1 - PLAYER COLLISION
53257
D009
SIZEPl
SIZE- PLAYER 1
53258
DOOA
M2PL
MIS 2 - PLAYER COLLISION
5325B
DOOA
SI2EP2
SIZE- PLAYER 2
53259
DOOB
M3PL
MIS 3 - PLAYER COLLISION
53259
DOOB
SIZEP3
SIZE- PLAYER 3
53260
DOOC
POPL
PLAY - PLAYER COLLISION
53260
DOOC
SIZEM
SIZES FOR ALL MISSILES
53261
DOOD
PIPL
PLAY 1 - PLAYER COLLISION
53261
DOOD
GRAFPO
GRAPHICS, PLAYER
53262
DOOE
GRAFPl
GRAPHICS, PLAYER 1
53262
DOOE
P2PL
PLAY 2 - PLAYER COLLISION
53263
DOOF
GRAFP2
GRAPHICS, PLAYER 2
53263
DOOF
P3PL
PLAY 3 - PLAYER COLLISION
53264
DO 1
BRAFP3
GRAPHICS, PLAYER 3
53264
DO 1
TRIGO
JOYSTICK TRIGGER
53265
DOll
GRAFM
GRAPHICS, ALL MISSILES
181
DEC ADDR
53265
53266
53266
53267
53267
5326B
5326B
53269
53270
53271
53272
53273
53274
53275
53277
53278
53279
53760
53760
5376 1
53761
53762
53762
53763
53763
53764
53764
53765
53765
53766
53766
53767
53767
3768
376B
53769
3769
5770
53770
53771
53773
53774
53774
53774
53775
53775
54016
54017
540 IB
54019
54272
54273
54274
54275
54276
54276
54277
54279
54281
542B2
54283
54284
54285
54286
54287
HEX ADR
DO 11
DO 12
DO 12
DO 13
DO 1 3
DO 1 4
DO 1 4
DO 15
DO 16
0017
DO 18
DO 19
DOIA
DO IB
DO 1 D
DO 1 E
DC) 1 F
D200
D200
D201
D201
D202
D202
D203
D203
D204
D204
D205
0205
D206
D206
D207
D207
D20B
D208
D209
D209
D20A
D20A
D20B
D20D
D20E
D20E
D20E
D20F
D20F
D300
D301
D302
D303
D400
D401
D402
D403
D404
DO 1 C
D405
D407
D409
D40A
D40B
D40C
D40D
D40E
D40F
LABEL
TRIGl
CQLPMO
TRIG2
COLPMl
TRIG3
PAL
C0LPM2
CDLPM3
COLPFO
COLPFl
C0LPF2
CQLPF3
COLBK
PRIOR
BRACTL
HITCLR
CONSOL
POTO
AUDFl
AUDCl
PQTl
AUDF2
PQT2
P0T3
AUDC2
AUDF3
P0T4
POTS
AUDC3
P0T6
AUDF4
P0T7
AUDC4
AUDCTL
ALLPOT
KBCODE
STIMER
RANDOM
SKREST
PDTGO
SEROUT
SERIN
IRQST
IRQEN
SKSTAT
SKCTL
PORTA
PORTB
PACTL
PBCTL
DMACTL
CHACTL
DLISTL
DLISTH
HSCRDL
VDELAY
VSCRDL
PMBASE
CHBASE
WSYNC
VCOUNT
PENH
PENV
NMIEN
NMIRES
FRED
CONTROL
FREQ
CONTROL
FREQ
CONTROL
4 FREQ
DESCRIP
JOYSTICK TRIG !
PLAYER-MISSILE COLOR
JOYSTICK TRIG 2
PLAYER-MISSILE 1 COLOR
JOYSTICK TRIG 3
PAL/NTSC INDICATOR
PLAYER-MISSILE 2 COLOR
PLAYER-MISSILE 3 COLOR
PLAYFIELD O COLOR
PLAYFIELD 1 COLOR
PLAYFIELD 2 COLOR
PLAYFIELD 3 COLOR
BACKGRND COLOR
PRIORITY SELECT
GRAPHIC CONTROL
COLLISION CLEAR
CONSOLE SWITCHES
POT
AUDIO CHANNEL 1
AUDIO CHANNEL 1
POT 1
AUDIO CHANNEL
POT 2
POT 3
AUDIO CHANNEL
AUDIO CHANNEL
POT 4
POT 5
AUDIO CHANNEL
POT 6
AUDIO CHANNEL
POT 7
AUDIO CHANNEL 4 CONTROL
AUDIO CONTROL
LINE POT PORT ST, READ 8
LAST KEY (INTERNAL CODE)
START TIMER
RANDOM NUMBER GENERATOR
SERIAL PORT STATUS RESET
START POT SCAN SEQUENCE
SERA I L PORT OUTPUT
SERIAL PORT INPUT
INTERUPT REQUEST STATUS
INTERRUPT REQUEST ENABLE
SERIAL PORT STATUS
~ SERIAL PORT CONTROL REG
PIA CON JACK I/O (A) *3C
PI A CON JACK I/O (A) *3C
PORT A CONTROL REG
PORT B CONTROL REGISTER
DIRECT MEM ACCESS CON
CHARACTER CONTROL
DISPLAY LIST POINTER LSB
DISPLAY LIST POINTER MSB
HORIZONTAL SCROLL
VERTICAL DELAY
VERTICAL SCROLL
PLAYER MISSILE BASE ADR
CHARACTER BASE ADR
WAIT FOR HORIZ SYNC
VERTICAL LINE CNTR
LIGHT PEN HORIZ VAL
LIGHT PEN VERTICAL POS
NON-MASK INTERUPT ENABLE
NON-MASK INTERUPT RESET
182
Index
Applications 3-5
Arrays 17,19,29,31,32,138
Assembly Language (See Machine
Language)
ATASCII 9,54,57,67,69,88,175
BASIC 7-16,17-18,19-23,26-35,
36-53,64-66,161
Binary SAVE/LOAD 157-158,160
Bit 37
Branching 12
Byte 26,37
Cartridges 19,156
Cassette 37,54,136-143,148-154
Characters 38,39,161
ATASCII (See ATASCII)
Text Modes 91-92
CLOAD 30
Clock 17,149-150
CLOSE 55
Color 18,67-68,76-79,85-86, 103, 1 18
Changing 68
Register 80
Computers
Background 2-6
in Business 2
in Education 3-4
Concatenation 14
Console Switches 172-173
Control Character 22,88
CSAVE 30
Cursor 67
DATA 12
Debug (See Error Messages; also
TRAP)
DEFFN 13,17
Disk 37,54,155-158,159-161,162-168
DOS 155-158
Editing 22
Error Messages 16,17,22,56,129-133
Files 15,54-63,136-143,155,161
Format 157
FOR/NEXT 11,149
Games 2,14-15,19
GET 17,22,55-57,67,78
GOTO 12,19,41,42,43,45
GOSUB (Also see Subroutines)
19,32,42,43
•Graphics 14,19,20-21,76-79,85-86,
87-89,102-104,105-110,111-114,
144-146
Player/Missile (See Player /Missile
Graphics)
Graphs 111,144-146
Hardcopy (See Printer)
Hardware (See Disk, Cassette, etc.)
IF/THEN 12,42,45
Input 12,18,22,57-58,60,80,116
Interface 174-177
Interface Module (See Interface)
lOCB 54-55
1/0 9,14-15,22,54-63,116
Joystick 80-84,99,121-128,169-171
Keyboard 4,5,1 16-1 17,169-170
Keywords 11,27,28-30,40
List 15,18,20,30,40-41,43
Load 15
Lock/Unlock 157,160
LPRINT 13,176
Machine Language 64-66,69-74,
102-104
Memory (Also see RAM, ROM)
26-28,36-53,160-161
Conservation of 142
Maps 31,100-101,103,143,
Appendix A
Modes 19,20-21,85,87-89,105-110
Music (See Sound, Voice)
Operating System 69,89
Output 12 (Also see Disk, Files,
Interface, etc.)
PEEK 9,13,36,45,107,138,169,172
Peripherals (See Disk, Cassette, etc.)
Player/Missile Graphics 93-104
POKE 9,13,14,15,61,67-68,69-70,82,
87,102-104,107-109,116
Pointers 31
POP 12
Printer 54,159
PUT 55-57,88-89
RAM 26,88,93-94,98,107
READ 12,18
ROM 87,88
RS-232, 174-177
SAVE 15
Screen 54,69-74
Self-modifying programming
136-143
SETCOLOR 20-21,67-68,77-78,85,
89,98,104,109
Sound 14,21,118-120,124,145
183
Index
Strings 10,19,32,61,69-70,139-140
Subroutines 12,19
Telecommunications 4
Timing (See Clock)
Tokens (See Keywords)
TRAP 43,88,129-130
Variable 10,18,19,20,27,29,32,36-40,
61,136-143
Voice 118
Window 85
XIO 15,54-63
Zero Page 26,38,39
184
Notes
18"^
Notes
1§6
Notes
187
Notes
188